diff -u -N -r asterisk-1.2.1.ori/codecs/Makefile asterisk-1.2.1/codecs/Makefile --- asterisk-1.2.1.ori/codecs/Makefile 2006-10-08 18:56:56.000000000 +0200 +++ asterisk-1.2.1/codecs/Makefile 2006-10-30 11:28:37.000000000 +0100 @@ -18,16 +18,6 @@ CFLAGS+=-fPIC endif -ifneq ($(wildcard g723.1/coder.c),) - MODG723=codec_g723_1.so - LIBG723=g723.1/libg723.a -endif - -ifneq ($(wildcard g723.1b/coder2.c),) - MODG723+=codec_g723_1b.so - LIBG723B=g723.1b/libg723b.a -endif - UI_SPEEX=$(wildcard $(CROSS_COMPILE_TARGET)/usr/include/speex.h) UIS_SPEEX=$(wildcard $(CROSS_COMPILE_TARGET)/usr/include/speex/speex.h) ULI_SPEEX=$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/speex.h) @@ -63,14 +53,16 @@ LIBGSM=gsm/lib/libgsm.a LIBGSMT=gsm/lib/libgsm.a LIBLPC10=lpc10/liblpc10.a +LIBG729=g729a_v11/libg729.a +LIBG723=g723_1/libg723.a ifeq ($(findstring BSD,${OSARCH}),BSD) CFLAGS+=-I$(CROSS_COMPILE_TARGET)/usr/local/include -L$(CROSS_COMPILE_TARGET)/usr/local/lib endif -CODECS+=$(MODG723) $(MODSPEEX) $(MODILBC) codec_gsm.so codec_lpc10.so \ +CODECS+=$(MODSPEEX) $(MODILBC) codec_gsm.so codec_lpc10.so \ codec_adpcm.so codec_ulaw.so codec_alaw.so codec_a_mu.so \ - codec_g726.so + codec_g723_1.so codec_g726.so codec_g729.so CFLAGS += $(EXTRA_CFLAGS) CODECS += $(EXTRA_CODEC_MODULES) @@ -79,39 +71,33 @@ clean: rm -f *.so *.o .depend - [ ! -d g723.1 ] || $(MAKE) -C g723.1 clean - [ ! -d g723.1b ] || $(MAKE) -C g723.1b clean + $(MAKE) -C g723_1 clean $(MAKE) -C gsm clean $(MAKE) -C lpc10 clean $(MAKE) -C ilbc clean + $(MAKE) -C g729a_v11 clean $(LIBG723): - $(MAKE) -C g723.1 all + $(MAKE) -C g723_1 all $(LIBGSM): $(MAKE) -C gsm lib/libgsm.a -$(LIBG723B): - $(MAKE) -C g723.1b all - $(LIBLPC10): $(MAKE) -C lpc10 all $(LIBILBC): $(MAKE) -C ilbc all +$(LIBG729): + $(MAKE) -C g729a_v11 all + $(MODILBC): codec_ilbc.o $(LIBILBC) $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBILBC) codec_g723_1.so : codec_g723_1.o $(LIBG723) $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBG723) -codec_g723_1b.o : codec_g723_1.c - $(CC) -c -o $@ $(CFLAGS) -DANNEX_B -Dsingle $< - -codec_g723_1b.so : codec_g723_1b.o $(LIBG723B) - $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBG723B) -lm - codec_gsm.so: codec_gsm.o $(LIBGSMT) $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBGSM) @@ -121,6 +107,9 @@ codec_lpc10.so: codec_lpc10.o $(LIBLPC10) $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBLPC10) -lm +codec_g729.so: codec_g729.o $(LIBG729) + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBG729) -lm + %.so : %.o $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} diff -u -N -r asterisk-1.2.1.ori/codecs/Makefile.orig asterisk-1.2.1/codecs/Makefile.orig --- asterisk-1.2.1.ori/codecs/Makefile.orig 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/Makefile.orig 2006-10-30 11:15:35.000000000 +0100 @@ -0,0 +1,137 @@ +# +# Asterisk -- A telephony toolkit for Linux. +# +# Makefile for codec modules +# +# Copyright (C) 1999-2005, Digium +# +# Mark Spencer +# +# This program is free software, distributed under the terms of +# the GNU General Public License +# + +ifeq (${OSARCH},CYGWIN) +CYGSOLINK=-Wl,--out-implib=lib$@.a -Wl,--export-all-symbols +CYGSOLIB=-L.. -L. -lasterisk.dll +else +CFLAGS+=-fPIC +endif + +ifneq ($(wildcard g723.1/coder.c),) + MODG723=codec_g723_1.so + LIBG723=g723.1/libg723.a +endif + +ifneq ($(wildcard g723.1b/coder2.c),) + MODG723+=codec_g723_1b.so + LIBG723B=g723.1b/libg723b.a +endif + +UI_SPEEX=$(wildcard $(CROSS_COMPILE_TARGET)/usr/include/speex.h) +UIS_SPEEX=$(wildcard $(CROSS_COMPILE_TARGET)/usr/include/speex/speex.h) +ULI_SPEEX=$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/speex.h) +ULIS_SPEEX=$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/speex/speex.h) +ifneq (${UI_SPEEX},) + MODSPEEX=codec_speex.so + LIBSPEEX+=-lspeex -lm +endif +ifneq (${UIS_SPEEX},) + MODSPEEX=codec_speex.so + CFLAGS+=-I$(CROSS_COMPILE_TARGET)/usr/include/speex + LIBSPEEX+=-lspeex -lm +endif +ifneq (${ULI_SPEEX},) + MODSPEEX=codec_speex.so + CFLAGS+=-I$(CROSS_COMPILE_TARGET)/usr/local/include + LIBSPEEX=-L$(CROSS_COMPILE_TARGET)/usr/local/lib + LIBSPEEX+=-lspeex -lm +endif +ifneq (${ULIS_SPEEX},) + MODSPEEX=codec_speex.so + CFLAGS+=-I$(CROSS_COMPILE_TARGET)/usr/local/include/speex + LIBSPEEX=-L$(CROSS_COMPILE_TARGET)/usr/local/lib + LIBSPEEX+=-lspeex -lm +endif + +ifneq ($(wildcard ilbc/iLBC_decode.h),) + MODILBC=codec_ilbc.so + LIBILBC=ilbc/libilbc.a +endif + + +LIBGSM=gsm/lib/libgsm.a +LIBGSMT=gsm/lib/libgsm.a +LIBLPC10=lpc10/liblpc10.a + +ifeq ($(findstring BSD,${OSARCH}),BSD) + CFLAGS+=-I$(CROSS_COMPILE_TARGET)/usr/local/include -L$(CROSS_COMPILE_TARGET)/usr/local/lib +endif + +CODECS+=$(MODG723) $(MODSPEEX) $(MODILBC) codec_gsm.so codec_lpc10.so \ + codec_adpcm.so codec_ulaw.so codec_alaw.so codec_a_mu.so \ + codec_g726.so + +CFLAGS += $(EXTRA_CFLAGS) +CODECS += $(EXTRA_CODEC_MODULES) + +all: depend $(CODECS) + +clean: + rm -f *.so *.o .depend + [ ! -d g723.1 ] || $(MAKE) -C g723.1 clean + [ ! -d g723.1b ] || $(MAKE) -C g723.1b clean + $(MAKE) -C gsm clean + $(MAKE) -C lpc10 clean + $(MAKE) -C ilbc clean + +$(LIBG723): + $(MAKE) -C g723.1 all + +$(LIBGSM): + $(MAKE) -C gsm lib/libgsm.a + +$(LIBG723B): + $(MAKE) -C g723.1b all + +$(LIBLPC10): + $(MAKE) -C lpc10 all + +$(LIBILBC): + $(MAKE) -C ilbc all + +$(MODILBC): codec_ilbc.o $(LIBILBC) + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBILBC) + +codec_g723_1.so : codec_g723_1.o $(LIBG723) + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBG723) + +codec_g723_1b.o : codec_g723_1.c + $(CC) -c -o $@ $(CFLAGS) -DANNEX_B -Dsingle $< + +codec_g723_1b.so : codec_g723_1b.o $(LIBG723B) + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBG723B) -lm + +codec_gsm.so: codec_gsm.o $(LIBGSMT) + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBGSM) + +$(MODSPEEX): codec_speex.o + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBSPEEX) + +codec_lpc10.so: codec_lpc10.o $(LIBLPC10) + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBLPC10) -lm + +%.so : %.o + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} + +ifneq ($(wildcard .depend),) + include .depend +endif + +install: all + for x in $(CODECS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done + +depend: .depend + +.depend: + ../build_tools/mkdep $(CFLAGS) `ls *.c` diff -u -N -r asterisk-1.2.1.ori/codecs/Makefile.rej asterisk-1.2.1/codecs/Makefile.rej --- asterisk-1.2.1.ori/codecs/Makefile.rej 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/Makefile.rej 2006-10-30 11:27:03.000000000 +0100 @@ -0,0 +1,70 @@ +*************** +*** 20,37 **** + CFLAGS+=-fPIC + endif + + SPEEX_PATH:=/usr/local/include /usr/include /usr/include/speex /usr/local/include/speex + SPEEX_SYSTEM_HEADERS:=$(firstword $(wildcard $(SPEEX_PATH:%=$(CROSS_COMPILE_TARGET)%/speex.h))) + ifeq (${SPEEX_SYSTEM_HEADERS},) +--- 20,25 ---- + CFLAGS+=-fPIC + endif + + SPEEX_PATH:=/usr/local/include /usr/include /usr/include/speex /usr/local/include/speex + SPEEX_SYSTEM_HEADERS:=$(firstword $(wildcard $(SPEEX_PATH:%=$(CROSS_COMPILE_TARGET)%/speex.h))) + ifeq (${SPEEX_SYSTEM_HEADERS},) +*************** +*** 71,109 **** + + clean: clean-depend + rm -f *.so *.o + $(MAKE) -C gsm clean + $(MAKE) -C lpc10 clean + $(MAKE) -C ilbc clean + + $(LIBG723): + + $(LIBGSM): + $(MAKE) -C gsm lib/libgsm.a + $(LIBLPC10): + $(MAKE) -C lpc10 all + + $(LIBILBC): + $(MAKE) -C ilbc all + + codec_ilbc.so: codec_ilbc.o $(LIBILBC) + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBILBC) + + codec_g723_1.so : codec_g723_1.o $(LIBG723) + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBG723) + +- codec_g723_1b.o : codec_g723_1.c +- $(CC) -c -o $@ $(CFLAGS) -DANNEX_B -Dsingle $< +- +- codec_g723_1b.so : codec_g723_1b.o $(LIBG723B) +- $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBG723B) -lm +- + codec_gsm.so: codec_gsm.o $(LIBGSMT) + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} $(LIBGSM) + +--- 61,93 ---- + + clean: clean-depend + rm -f *.so *.o ++ $(MAKE) -C g723_1 clean + $(MAKE) -C gsm clean + $(MAKE) -C lpc10 clean + $(MAKE) -C ilbc clean + + $(LIBG723): ++ $(MAKE) -C g723_1 all + + $(LIBGSM): + $(MAKE) -C gsm lib/libgsm.a + + $(LIBLPC10): + $(MAKE) -C lpc10 all + + $(LIBILBC): + $(MAKE) -C ilbc all + diff -u -N -r asterisk-1.2.1.ori/codecs/codec_g723_1.c asterisk-1.2.1/codecs/codec_g723_1.c --- asterisk-1.2.1.ori/codecs/codec_g723_1.c 2005-11-29 19:24:39.000000000 +0100 +++ asterisk-1.2.1/codecs/codec_g723_1.c 2006-10-30 11:37:42.000000000 +0100 @@ -51,23 +51,9 @@ #include "asterisk/logger.h" #include "asterisk/channel.h" -#ifdef ANNEX_B -#include "g723.1b/typedef2.h" -#include "g723.1b/cst2.h" -#include "g723.1b/coder2.h" -#include "g723.1b/decod2.h" -#include "g723.1b/deccng2.h" -#include "g723.1b/codcng2.h" -#include "g723.1b/vad2.h" -#else -#include "g723.1/typedef.h" -#include "g723.1/cst_lbc.h" -#include "g723.1/coder.h" -#include "g723.1/decod.h" -#include "g723.1/dec_cng.h" -#include "g723.1/cod_cng.h" -#include "g723.1/vad.h" -#endif +#include "g723_1/typedef.h" +#include "g723_1/coder.h" +#include "g723_1/decod.h" /* Sample frame data */ #include "slin_g723_ex.h" @@ -76,11 +62,7 @@ AST_MUTEX_DEFINE_STATIC(localuser_lock); static int localusecnt=0; -#ifdef ANNEX_B -static char *tdesc = "Annex B (floating point) G.723.1/PCM16 Codec Translator"; -#else static char *tdesc = "Annex A (fixed point) G.723.1/PCM16 Codec Translator"; -#endif /* Globals */ Flag UsePf = True; @@ -90,7 +72,8 @@ enum Crate WrkRate = Rate63; struct g723_encoder_pvt { - struct cod_state cod; + CODSTATDEF *CodStat; + struct ast_frame f; /* Space to build offset */ char offset[AST_FRIENDLY_OFFSET]; @@ -102,7 +85,8 @@ }; struct g723_decoder_pvt { - struct dec_state dec; + DECSTATDEF *DecStat; + struct ast_frame f; /* Space to build offset */ char offset[AST_FRIENDLY_OFFSET]; @@ -116,8 +100,7 @@ struct g723_decoder_pvt *tmp; tmp = malloc(sizeof(struct g723_decoder_pvt)); if (tmp) { - Init_Decod(&tmp->dec); - Init_Dec_Cng(&tmp->dec); + tmp->DecStat = Init_Decod(1, Rate63); tmp->tail = 0; localusecnt++; ast_update_use_count(); @@ -160,12 +143,7 @@ struct g723_encoder_pvt *tmp; tmp = malloc(sizeof(struct g723_encoder_pvt)); if (tmp) { - Init_Coder(&tmp->cod); - /* Init Comfort Noise Functions */ - if( UseVx ) { - Init_Vad(&tmp->cod); - Init_Cod_Cng(&tmp->cod); - } + tmp->CodStat = Init_Coder(1, 1, Rate63); localusecnt++; ast_update_use_count(); tmp->tail = 0; @@ -192,16 +170,6 @@ /* Reset tail pointer */ tmp->tail = 0; -#if 0 - /* Save the frames */ - { - static int fd2 = -1; - if (fd2 == -1) { - fd2 = open("g723.example", O_WRONLY | O_CREAT | O_TRUNC, 0644); - } - write(fd2, tmp->f.data, tmp->f.datalen); - } -#endif return &tmp->f; } @@ -231,10 +199,6 @@ struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt; int len = 0; int res; -#ifdef ANNEX_B - FLOAT tmpdata[Frame]; - int x; -#endif while(len < f->datalen) { /* Assuming there's space left, decode into the current buffer at the tail location */ @@ -248,13 +212,7 @@ return -1; } if (tmp->tail + Frame < sizeof(tmp->buf)/2) { -#ifdef ANNEX_B - Decod(&tmp->dec, tmpdata, f->data + len, 0); - for (x=0;xbuf + tmp->tail)[x] = (short)(tmpdata[x]); -#else - Decod(&tmp->dec, tmp->buf + tmp->tail, f->data + len, 0); -#endif + Decod(tmp->DecStat, tmp->buf + tmp->tail, f->data + len, 0); tmp->tail+=Frame; } else { ast_log(LOG_WARNING, "Out of buffer space\n"); @@ -285,10 +243,6 @@ static struct ast_frame *lintog723_frameout(struct ast_translator_pvt *pvt) { struct g723_encoder_pvt *tmp = (struct g723_encoder_pvt *)pvt; -#ifdef ANNEX_B - int x; - FLOAT tmpdata[Frame]; -#endif int cnt=0; /* We can't work on anything less than a frame in size */ if (tmp->tail < Frame) @@ -305,13 +259,7 @@ ast_log(LOG_WARNING, "Out of buffer space\n"); return NULL; } -#ifdef ANNEX_B - for (x=0;xbuf[x]; - Coder(&tmp->cod, tmpdata, tmp->outbuf + cnt); -#else - Coder(&tmp->cod, tmp->buf, tmp->outbuf + cnt); -#endif + Coder(tmp->CodStat, tmp->buf, tmp->outbuf + cnt); /* Assume 8000 Hz */ tmp->f.samples += 240; cnt += g723_len(tmp->outbuf[cnt]); @@ -322,57 +270,44 @@ } tmp->f.datalen = cnt; tmp->f.data = tmp->outbuf; -#if 0 - /* Save to a g723 sample output file... */ - { - static int fd = -1; - int delay = htonl(30); - short size; - if (fd < 0) - fd = open("trans.g723", O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd < 0) - ast_log(LOG_WARNING, "Unable to create demo\n"); - write(fd, &delay, 4); - size = htons(tmp->f.datalen); - write(fd, &size, 2); - write(fd, tmp->f.data, tmp->f.datalen); - } -#endif return &tmp->f; } -static void g723_destroy(struct ast_translator_pvt *pvt) +static void lintog723_destroy(struct ast_translator_pvt *pvt) +{ + struct g723_encoder_pvt *tmp = (struct g723_encoder_pvt *)pvt; + free(tmp->CodStat); + free(pvt); + localusecnt--; + ast_update_use_count(); +} + +static void g723tolin_destroy(struct ast_translator_pvt *pvt) { + struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt; + free(tmp->DecStat); free(pvt); localusecnt--; ast_update_use_count(); } static struct ast_translator g723tolin = -#ifdef ANNEX_B - { "g723tolinb", -#else { "g723tolin", -#endif AST_FORMAT_G723_1, AST_FORMAT_SLINEAR, g723tolin_new, g723tolin_framein, g723tolin_frameout, - g723_destroy, + g723tolin_destroy, g723tolin_sample }; static struct ast_translator lintog723 = -#ifdef ANNEX_B - { "lintog723b", -#else { "lintog723", -#endif AST_FORMAT_SLINEAR, AST_FORMAT_G723_1, lintog723_new, lintog723_framein, lintog723_frameout, - g723_destroy, + lintog723_destroy, lintog723_sample }; diff -u -N -r asterisk-1.2.1.ori/codecs/codec_g723_1.c.orig asterisk-1.2.1/codecs/codec_g723_1.c.orig --- asterisk-1.2.1.ori/codecs/codec_g723_1.c.orig 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/codec_g723_1.c.orig 2005-11-29 19:24:39.000000000 +0100 @@ -0,0 +1,418 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * The G.723.1 code is not included in the Asterisk distribution because + * it is covered with patents, and in spite of statements to the contrary, + * the "technology" is extremely expensive to license. + * + * Copyright (C) 1999 - 2005, Digium, Inc. + * + * Mark Spencer + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Translate between signed linear and G.723.1 + * + * \ingroup codecs + */ + +#define TYPE_HIGH 0x0 +#define TYPE_LOW 0x1 +#define TYPE_SILENCE 0x2 +#define TYPE_DONTSEND 0x3 +#define TYPE_MASK 0x3 + +#include +#include +#include +#include +#include +#include +#include + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $") + +#include "asterisk/lock.h" +#include "asterisk/translate.h" +#include "asterisk/module.h" +#include "asterisk/logger.h" +#include "asterisk/channel.h" + +#ifdef ANNEX_B +#include "g723.1b/typedef2.h" +#include "g723.1b/cst2.h" +#include "g723.1b/coder2.h" +#include "g723.1b/decod2.h" +#include "g723.1b/deccng2.h" +#include "g723.1b/codcng2.h" +#include "g723.1b/vad2.h" +#else +#include "g723.1/typedef.h" +#include "g723.1/cst_lbc.h" +#include "g723.1/coder.h" +#include "g723.1/decod.h" +#include "g723.1/dec_cng.h" +#include "g723.1/cod_cng.h" +#include "g723.1/vad.h" +#endif + +/* Sample frame data */ +#include "slin_g723_ex.h" +#include "g723_slin_ex.h" + +AST_MUTEX_DEFINE_STATIC(localuser_lock); +static int localusecnt=0; + +#ifdef ANNEX_B +static char *tdesc = "Annex B (floating point) G.723.1/PCM16 Codec Translator"; +#else +static char *tdesc = "Annex A (fixed point) G.723.1/PCM16 Codec Translator"; +#endif + +/* Globals */ +Flag UsePf = True; +Flag UseHp = True; +Flag UseVx = True; + +enum Crate WrkRate = Rate63; + +struct g723_encoder_pvt { + struct cod_state cod; + struct ast_frame f; + /* Space to build offset */ + char offset[AST_FRIENDLY_OFFSET]; + /* Buffer for our outgoing frame */ + char outbuf[8000]; + /* Enough to store a full second */ + short buf[8000]; + int tail; +}; + +struct g723_decoder_pvt { + struct dec_state dec; + struct ast_frame f; + /* Space to build offset */ + char offset[AST_FRIENDLY_OFFSET]; + /* Enough to store a full second */ + short buf[8000]; + int tail; +}; + +static struct ast_translator_pvt *g723tolin_new(void) +{ + struct g723_decoder_pvt *tmp; + tmp = malloc(sizeof(struct g723_decoder_pvt)); + if (tmp) { + Init_Decod(&tmp->dec); + Init_Dec_Cng(&tmp->dec); + tmp->tail = 0; + localusecnt++; + ast_update_use_count(); + } + return (struct ast_translator_pvt *)tmp; +} + +static struct ast_frame *lintog723_sample(void) +{ + static struct ast_frame f; + f.frametype = AST_FRAME_VOICE; + f.subclass = AST_FORMAT_SLINEAR; + f.datalen = sizeof(slin_g723_ex); + /* Assume 8000 Hz */ + f.samples = sizeof(slin_g723_ex)/2; + f.mallocd = 0; + f.offset = 0; + f.src = __PRETTY_FUNCTION__; + f.data = slin_g723_ex; + return &f; +} + +static struct ast_frame *g723tolin_sample(void) +{ + static struct ast_frame f; + f.frametype = AST_FRAME_VOICE; + f.subclass = AST_FORMAT_G723_1; + f.datalen = sizeof(g723_slin_ex); + /* All frames are 30 ms long */ + f.samples = 240; + f.mallocd = 0; + f.offset = 0; + f.src = __PRETTY_FUNCTION__; + f.data = g723_slin_ex; + return &f; +} + +static struct ast_translator_pvt *lintog723_new(void) +{ + struct g723_encoder_pvt *tmp; + tmp = malloc(sizeof(struct g723_encoder_pvt)); + if (tmp) { + Init_Coder(&tmp->cod); + /* Init Comfort Noise Functions */ + if( UseVx ) { + Init_Vad(&tmp->cod); + Init_Cod_Cng(&tmp->cod); + } + localusecnt++; + ast_update_use_count(); + tmp->tail = 0; + } + return (struct ast_translator_pvt *)tmp; +} + +static struct ast_frame *g723tolin_frameout(struct ast_translator_pvt *pvt) +{ + struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt; + if (!tmp->tail) + return NULL; + /* Signed linear is no particular frame size, so just send whatever + we have in the buffer in one lump sum */ + tmp->f.frametype = AST_FRAME_VOICE; + tmp->f.subclass = AST_FORMAT_SLINEAR; + tmp->f.datalen = tmp->tail * 2; + /* Assume 8000 Hz */ + tmp->f.samples = tmp->tail; + tmp->f.mallocd = 0; + tmp->f.offset = AST_FRIENDLY_OFFSET; + tmp->f.src = __PRETTY_FUNCTION__; + tmp->f.data = tmp->buf; + /* Reset tail pointer */ + tmp->tail = 0; + +#if 0 + /* Save the frames */ + { + static int fd2 = -1; + if (fd2 == -1) { + fd2 = open("g723.example", O_WRONLY | O_CREAT | O_TRUNC, 0644); + } + write(fd2, tmp->f.data, tmp->f.datalen); + } +#endif + return &tmp->f; +} + +static int g723_len(unsigned char buf) +{ + switch(buf & TYPE_MASK) { + case TYPE_DONTSEND: + return 0; + break; + case TYPE_SILENCE: + return 4; + break; + case TYPE_HIGH: + return 24; + break; + case TYPE_LOW: + return 20; + break; + default: + ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK); + } + return -1; +} + +static int g723tolin_framein(struct ast_translator_pvt *pvt, struct ast_frame *f) +{ + struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt; + int len = 0; + int res; +#ifdef ANNEX_B + FLOAT tmpdata[Frame]; + int x; +#endif + while(len < f->datalen) { + /* Assuming there's space left, decode into the current buffer at + the tail location */ + res = g723_len(((unsigned char *)f->data + len)[0]); + if (res < 0) { + ast_log(LOG_WARNING, "Invalid data\n"); + return -1; + } + if (res + len > f->datalen) { + ast_log(LOG_WARNING, "Measured length exceeds frame length\n"); + return -1; + } + if (tmp->tail + Frame < sizeof(tmp->buf)/2) { +#ifdef ANNEX_B + Decod(&tmp->dec, tmpdata, f->data + len, 0); + for (x=0;xbuf + tmp->tail)[x] = (short)(tmpdata[x]); +#else + Decod(&tmp->dec, tmp->buf + tmp->tail, f->data + len, 0); +#endif + tmp->tail+=Frame; + } else { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + len += res; + } + return 0; +} + +static int lintog723_framein(struct ast_translator_pvt *pvt, struct ast_frame *f) +{ + /* Just add the frames to our stream */ + /* XXX We should look at how old the rest of our stream is, and if it + is too old, then we should overwrite it entirely, otherwise we can + get artifacts of earlier talk that do not belong */ + struct g723_encoder_pvt *tmp = (struct g723_encoder_pvt *)pvt; + if (tmp->tail + f->datalen/2 < sizeof(tmp->buf) / 2) { + memcpy(&tmp->buf[tmp->tail], f->data, f->datalen); + tmp->tail += f->datalen/2; + } else { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + return 0; +} + +static struct ast_frame *lintog723_frameout(struct ast_translator_pvt *pvt) +{ + struct g723_encoder_pvt *tmp = (struct g723_encoder_pvt *)pvt; +#ifdef ANNEX_B + int x; + FLOAT tmpdata[Frame]; +#endif + int cnt=0; + /* We can't work on anything less than a frame in size */ + if (tmp->tail < Frame) + return NULL; + tmp->f.frametype = AST_FRAME_VOICE; + tmp->f.subclass = AST_FORMAT_G723_1; + tmp->f.offset = AST_FRIENDLY_OFFSET; + tmp->f.src = __PRETTY_FUNCTION__; + tmp->f.samples = 0; + tmp->f.mallocd = 0; + while(tmp->tail >= Frame) { + /* Encode a frame of data */ + if (cnt + 24 >= sizeof(tmp->outbuf)) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return NULL; + } +#ifdef ANNEX_B + for (x=0;xbuf[x]; + Coder(&tmp->cod, tmpdata, tmp->outbuf + cnt); +#else + Coder(&tmp->cod, tmp->buf, tmp->outbuf + cnt); +#endif + /* Assume 8000 Hz */ + tmp->f.samples += 240; + cnt += g723_len(tmp->outbuf[cnt]); + tmp->tail -= Frame; + /* Move the data at the end of the buffer to the front */ + if (tmp->tail) + memmove(tmp->buf, tmp->buf + Frame, tmp->tail * 2); + } + tmp->f.datalen = cnt; + tmp->f.data = tmp->outbuf; +#if 0 + /* Save to a g723 sample output file... */ + { + static int fd = -1; + int delay = htonl(30); + short size; + if (fd < 0) + fd = open("trans.g723", O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + ast_log(LOG_WARNING, "Unable to create demo\n"); + write(fd, &delay, 4); + size = htons(tmp->f.datalen); + write(fd, &size, 2); + write(fd, tmp->f.data, tmp->f.datalen); + } +#endif + return &tmp->f; +} + +static void g723_destroy(struct ast_translator_pvt *pvt) +{ + free(pvt); + localusecnt--; + ast_update_use_count(); +} + +static struct ast_translator g723tolin = +#ifdef ANNEX_B + { "g723tolinb", +#else + { "g723tolin", +#endif + AST_FORMAT_G723_1, AST_FORMAT_SLINEAR, + g723tolin_new, + g723tolin_framein, + g723tolin_frameout, + g723_destroy, + g723tolin_sample + }; + +static struct ast_translator lintog723 = +#ifdef ANNEX_B + { "lintog723b", +#else + { "lintog723", +#endif + AST_FORMAT_SLINEAR, AST_FORMAT_G723_1, + lintog723_new, + lintog723_framein, + lintog723_frameout, + g723_destroy, + lintog723_sample + }; + +int unload_module(void) +{ + int res; + ast_mutex_lock(&localuser_lock); + res = ast_unregister_translator(&lintog723); + if (!res) + res = ast_unregister_translator(&g723tolin); + if (localusecnt) + res = -1; + ast_mutex_unlock(&localuser_lock); + return res; +} + +int load_module(void) +{ + int res; + res=ast_register_translator(&g723tolin); + if (!res) + res=ast_register_translator(&lintog723); + else + ast_unregister_translator(&g723tolin); + return res; +} + +char *description(void) +{ + return tdesc; +} + +int usecount(void) +{ + int res; + STANDARD_USECOUNT(res); + return res; +} + +char *key(void) +{ + return ASTERISK_GPL_KEY; +} diff -u -N -r asterisk-1.2.1.ori/codecs/codec_g723_1.c.rej asterisk-1.2.1/codecs/codec_g723_1.c.rej --- asterisk-1.2.1.ori/codecs/codec_g723_1.c.rej 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/codec_g723_1.c.rej 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,40 @@ +*************** +*** 115,122 **** + { + struct g723_decoder_pvt *tmp; + if ((tmp = ast_malloc(sizeof(*tmp)))) { +- Init_Decod(&tmp->dec); +- Init_Dec_Cng(&tmp->dec); + tmp->tail = 0; + localusecnt++; + ast_update_use_count(); +--- 99,105 ---- + { + struct g723_decoder_pvt *tmp; + if ((tmp = ast_malloc(sizeof(*tmp)))) { ++ tmp->DecStat = Init_Decod(1, Rate63); + tmp->tail = 0; + localusecnt++; + ast_update_use_count(); +*************** +*** 158,169 **** + { + struct g723_encoder_pvt *tmp; + if ((tmp = ast_malloc(sizeof(*tmp)))) { +- Init_Coder(&tmp->cod); +- /* Init Comfort Noise Functions */ +- if( UseVx ) { +- Init_Vad(&tmp->cod); +- Init_Cod_Cng(&tmp->cod); +- } + localusecnt++; + ast_update_use_count(); + tmp->tail = 0; +--- 141,147 ---- + { + struct g723_encoder_pvt *tmp; + if ((tmp = ast_malloc(sizeof(*tmp)))) { ++ tmp->CodStat = Init_Coder(1, 1, Rate63); + localusecnt++; + ast_update_use_count(); + tmp->tail = 0; diff -u -N -r asterisk-1.2.1.ori/codecs/codec_g729.c asterisk-1.2.1/codecs/codec_g729.c --- asterisk-1.2.1.ori/codecs/codec_g729.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/codec_g729.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,294 @@ +/* + * G729 codec for Asterisk + * + * For G.729(,A,B) royalty payments, see http://www.sipro.com + * + * WARNING: please make sure you are sitting down before looking + * at their price list. + * + * This source file is Copyright (C) 2004 Ready Technology Limited + * This code is provided for educational purposes and is not warranted + * to be fit for commercial use. There is no warranty of any kind. + * + * Author: daniel@readytechnology.co.uk + */ +#include "asterisk/lock.h" +#include "asterisk/translate.h" +#include "asterisk/module.h" +#include "asterisk/logger.h" +#include "asterisk/channel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "g729a_v11/typedef.h" +#include "g729a_v11/basic_op.h" +#include "g729a_v11/ld8a.h" +#include "g729a_v11/tab_ld8a.h" +#include "g729a_v11/util.h" +#include "g729a_v11/pre_proc.h" + +/* Sample frame data */ +#include "slin_g729_ex.h" +#include "g729_slin_ex.h" + +AST_MUTEX_DEFINE_STATIC(localuser_lock); + +static int localusecnt=0; + +static char *tdesc = "G729/PCM16 (signed linear) Codec Translator, based on ITU Reference code"; + +struct ast_translator_pvt { + + struct ast_frame f; + + CodState *coder; + DecState *decoder; + + short pcm_buf[8000]; + unsigned char bitstream_buf[1000]; + + int tail; +}; + +#define g729_coder_pvt ast_translator_pvt + +static struct ast_translator_pvt *lintog729_new(void) { + struct g729_coder_pvt *tmp; + tmp = malloc(sizeof(struct g729_coder_pvt)); + if(tmp) { + + tmp->coder = Init_Coder_ld8a(); + Init_Pre_Process(tmp->coder); + tmp->decoder = NULL; + + tmp->tail = 0; + localusecnt++; + } + return tmp; +} + +static struct ast_translator_pvt *g729tolin_new(void) { + struct g729_coder_pvt *tmp; + tmp = malloc(sizeof(struct g729_coder_pvt)); + if(tmp) { + tmp->decoder = Init_Decod_ld8a(); + Init_Post_Filter(tmp->decoder); + Init_Post_Process(tmp->decoder); + tmp->coder = NULL; + + tmp->tail = 0; + localusecnt++; + } + return tmp; +} + +static struct ast_frame *lintog729_sample(void) { + static struct ast_frame f; + f.frametype = AST_FRAME_VOICE; + f.subclass = AST_FORMAT_SLINEAR; + f.datalen = sizeof(slin_g729_ex); + f.samples = sizeof(slin_g729_ex) / 2; + f.mallocd = 0; + f.offset = 0; + f.src = __PRETTY_FUNCTION__; + f.data = slin_g729_ex; + return &f; +} + +static struct ast_frame *g729tolin_sample(void) { + static struct ast_frame f; + f.frametype = AST_FRAME_VOICE; + f.subclass = AST_FORMAT_G729A; + f.datalen = sizeof(g729_slin_ex); + f.samples = 240; + f.mallocd = 0; + f.offset = 0; + f.src = __PRETTY_FUNCTION__; + f.data = g729_slin_ex; + return &f; +} + +/** + * Retrieve a frame that has already been decompressed + */ +static struct ast_frame *g729tolin_frameout(struct ast_translator_pvt *tmp) { + if(!tmp->tail) + return NULL; + tmp->f.frametype = AST_FRAME_VOICE; + tmp->f.subclass = AST_FORMAT_SLINEAR; + tmp->f.datalen = tmp->tail * 2; + tmp->f.samples = tmp->tail; + tmp->f.mallocd = 0; + tmp->f.offset = AST_FRIENDLY_OFFSET; + tmp->f.src = __PRETTY_FUNCTION__; + tmp->f.data = tmp->pcm_buf; + tmp->tail = 0; + return &tmp->f; +} + +/** + * Accept a frame and decode it at the end of the current buffer + */ +static int g729tolin_framein(struct ast_translator_pvt *tmp, struct ast_frame *f) { + int x; + int frameSize = 0; + + for(x = 0; x < f->datalen; x += frameSize) { + if((f->datalen - x) == 2) + frameSize = 2; /* VAD frame */ + else + frameSize = 10; /* Regular frame */ + + if(tmp->tail + 80 < sizeof(tmp->pcm_buf) / 2) { + + { + Word16 i; + Word16 *synth; + Word16 parm[PRM_SIZE + 1]; + + Restore_Params(f->data + x, &parm[1]); + synth = tmp->decoder->synth_buf + M; + + parm[0] = 1; + for (i = 0; i < PRM_SIZE; i++) { + if (parm[i + 1] != 0) { + parm[0] = 0; + break; + } + } + + parm[4] = Check_Parity_Pitch(parm[3], parm[4]); + + Decod_ld8a(tmp->decoder, parm, synth, tmp->decoder->Az_dec, tmp->decoder->T2, &tmp->decoder->bad_lsf); + Post_Filter(tmp->decoder, synth, tmp->decoder->Az_dec, tmp->decoder->T2); + Post_Process(tmp->decoder, synth, L_FRAME); + + memmove(tmp->pcm_buf + tmp->tail, synth, 2 * L_FRAME); + } + + tmp->tail += 80; + } else { + ast_log(LOG_WARNING, "Out of G.729 buffer space\n"); + return -1; + } + } + return 0; +} + +static int lintog729_framein(struct ast_translator_pvt *tmp, struct ast_frame *f) { + if(tmp->tail + f->datalen/2 < sizeof(tmp->pcm_buf) / 2) { + memcpy((tmp->pcm_buf + tmp->tail), f->data, f->datalen); + tmp->tail += f->datalen/2; + } else { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + return 0; +} + +static struct ast_frame *lintog729_frameout(struct ast_translator_pvt *tmp) { + + int x = 0; + + if(tmp->tail < 80) + return NULL; + tmp->f.frametype = AST_FRAME_VOICE; + tmp->f.subclass = AST_FORMAT_G729A; + tmp->f.mallocd = 0; + tmp->f.offset = AST_FRIENDLY_OFFSET; + tmp->f.src = __PRETTY_FUNCTION__; + tmp->f.data = tmp->bitstream_buf; + while(tmp->tail >= 80) { + if((x+1) * 10 >= sizeof(tmp->bitstream_buf)) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + break; + } + + { + Word16 parm[PRM_SIZE]; + + Copy ((Word16 *) tmp->pcm_buf, tmp->coder->new_speech, 80); + Pre_Process(tmp->coder, tmp->coder->new_speech, 80); + Coder_ld8a(tmp->coder, parm); + Store_Params(parm, tmp->bitstream_buf + (x * 10)); + } + + tmp->tail -= 80; + if(tmp->tail) + memmove(tmp->pcm_buf, tmp->pcm_buf + 80, tmp->tail * 2); + x++; + } + tmp->f.datalen = x * 10; + tmp->f.samples = x * 80; + + return &(tmp->f); +} + +static void g729_release(struct ast_translator_pvt *pvt) { + if (pvt->coder) + free (pvt->coder); + if (pvt->decoder) + free (pvt->decoder); + localusecnt--; +} + +static struct ast_translator g729tolin = { + "g729tolin", + AST_FORMAT_G729A, AST_FORMAT_SLINEAR, + g729tolin_new, + g729tolin_framein, + g729tolin_frameout, + g729_release, + g729tolin_sample }; + +static struct ast_translator lintog729 = { + "lintog729", + AST_FORMAT_SLINEAR, AST_FORMAT_G729A, + lintog729_new, + lintog729_framein, + lintog729_frameout, + g729_release, + lintog729_sample }; + +int load_module(void) { + int res; + res = ast_register_translator(&g729tolin); + if(!res) + res = ast_register_translator(&lintog729); + else + ast_unregister_translator(&g729tolin); + return res; +} + +int unload_module(void) { + int res; + ast_mutex_lock(&localuser_lock); + res = ast_unregister_translator(&lintog729); + if(!res) + res = ast_unregister_translator(&g729tolin); + if(localusecnt) + res = -1; + ast_mutex_unlock(&localuser_lock); + return res; +} + +char *description(void) { + return tdesc; +} + +int usecount(void) { + int res; + STANDARD_USECOUNT(res); + return res; +} + +char *key() { + return ASTERISK_GPL_KEY; +} + diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/Makefile asterisk-1.2.1/codecs/g723_1/Makefile --- asterisk-1.2.1.ori/codecs/g723_1/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/Makefile 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,33 @@ +ARCH=$(PROC) +CFLAGS+=-Wall -O3 -funroll-loops +ifneq (${OSARCH},CYGWIN) +CFLAGS += -fPIC +endif +LIB=libg723.a + +OBJS=\ +basop.o \ +cod_cng.o \ +coder.o \ +decod.o \ +exc_lbc.o \ +lbccodec.o \ +lpc.o \ +lsp.o \ +tab_lbc.o \ +tame.o \ +util_cng.o \ +util_lbc.o \ +vad.o + +all: $(LIB) + +$(LIB): $(OBJS) + ar cr $(LIB) $(OBJS) + ranlib $(LIB) + +clean: + rm -f $(LIB) *.o + +install: + diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/basop.c asterisk-1.2.1/codecs/g723_1/basop.c --- asterisk-1.2.1.ori/codecs/g723_1/basop.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/basop.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,1619 @@ + +#include +#include +#include "typedef.h" +#include "basop.h" + +static Word16 sature (Word32 L_var1); + +/* +** +** Function Name : sature +** +** Purpose : +** +** Limit the 32 bit input to the range of a 16 bit word. +** +** Inputs : +** +** L_var1 +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +sature (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 > 0X00007fffL) { + var_out = MAX_16; + } + else { + if (L_var1 < (Word32) 0xffff8000L) { + var_out = MIN_16; + } + else { + var_out = extract_l (L_var1); + } + } + return (var_out); +} + +/* +** +** Function Name : add +** +** Purpose : +** +** Performs the addition (var1+var2) with overflow control and saturation; +** the 16 bit result is set at +32767 when overflow occurs or at -32768 +** when underflow occurs. +** +** Complexity weight : 1 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +add (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_somme; + + L_somme = (Word32) var1 + (Word32) var2; + var_out = sature (L_somme); + return (var_out); +} + +/* +** +** Function Name : sub +** +** Purpose : +** +** Performs the subtraction (var1+var2) with overflow control and satu- +** ration; the 16 bit result is set at +32767 when overflow occurs or at +** -32768 when underflow occurs. +** +** Complexity weight : 1 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +sub (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_diff; + + L_diff = (Word32) var1 - (Word32) var2; + var_out = sature (L_diff); + return (var_out); +} + +/* +** +** Function Name : abs_s +** +** Purpose : +** +** Absolute value of var1; abs_s(-32768) = 32767. +** +** Complexity weight : 1 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0x0000 0000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +abs_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == (Word16) 0X8000) { + var_out = MAX_16; + } + else { + if (var1 < 0) { + var_out = -var1; + } + else { + var_out = var1; + } + } + + return (var_out); +} + +/* +** +** Function Name : shl +** +** Purpose : +** +** Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill +** the var2 LSB of the result. If var2 is negative, arithmetically shift +** var1 right by -var2 with sign extension. Saturate the result in case of +** underflows or overflows. +** +** Complexity weight : 1 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +shl (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_result; + + if (var2 < 0) { + var_out = shr (var1, (Word16) - var2); + } + else { + L_result = (Word32) var1 *((Word32) 1 << var2); + if (((var2 > 15) && (var1 != 0)) | + (L_result != (Word32) ((Word16) L_result))) { + var_out = (var1 > 0) ? MAX_16 : MIN_16; + } + else { + var_out = extract_l (L_result); + } + } + + return (var_out); +} + +/* +** +** Function Name : shr +** +** Purpose : +** +** Arithmetically shift the 16 bit input var1 right var2 positions with +** sign extension. If var2 is negative, arithmetically shift var1 left by +** -var2 with sign extension. Saturate the result in case of underflows or +** overflows. +** +** Complexity weight : 1 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +shr (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 < 0) { + var_out = shl (var1, (Word16) - var2); + } + else { + if (var2 >= 15) { + var_out = (var1 < (Word16) 0) ? (Word16) - 1 : (Word16) 0; + } + else { + if (var1 < 0) { + var_out = ~((~var1) >> var2); + } + else { + var_out = var1 >> var2; + } + } + } + + return (var_out); +} + +/* +** +** Function Name : mult +** +** Purpose : +** +** Performs the multiplication of var1 by var2 and gives a 16 bit result +** which is scaled i.e.: +** mult(var1,var2) = shr((var1 times var2),15) and +** mult(-32768,-32768) = 32767. +** +** Complexity weight : 1 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +mult (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_produit; + + L_produit = (Word32) var1 *(Word32) var2; + + L_produit = (L_produit & (Word32) 0xffff8000L) >> 15; + + if (L_produit & (Word32) 0x00010000L) { + L_produit |= (Word32) 0xffff0000L; + } + var_out = sature (L_produit); + return (var_out); +} + + +/* +** +** Function Name : L_mult +** +** Purpose : +** +** L_mult is the 32 bit result of the multiplication of var1 times var2 +** with one shift left i.e.: +** L_mult(var1,var2) = shl((var1 times var2),1) and +** L_mult(-32768,-32768) = 2147483647. +** +** Complexity weight : 1 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_mult (Word16 var1, Word16 var2) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 *(Word32) var2; + if (L_var_out != (Word32) 0x40000000L) { + L_var_out *= 2L; + } + else { + L_var_out = MAX_32; + } + + return (L_var_out); +} + + +/* +** +** Function Name : negate +** +** Purpose : +** +** Negate var1 with saturation, saturate in the case where input is -32768: +** negate(var1) = sub(0,var1). +** +** Complexity weight : 1 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +negate (Word16 var1) +{ + Word16 var_out; + + var_out = (var1 == MIN_16) ? MAX_16 : -var1; + return (var_out); +} + + +/* +** +** Function Name : extract_h +** +** Purpose : +** +** Return the 16 MSB of L_var1. +** +** Complexity weight : 1 +** +** Inputs : +** +** L_var1 +** 32 bit long signed integer (Word32 ) whose value falls in the +** range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +extract_h (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) (L_var1 >> 16); + return (var_out); +} + +/* +** +** Function Name : extract_l +** +** Purpose : +** +** Return the 16 LSB of L_var1. +** +** Complexity weight : 1 +** +** Inputs : +** +** L_var1 +** 32 bit long signed integer (Word32 ) whose value falls in the +** range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +extract_l (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) L_var1; + return (var_out); +} + + +/* +** +** Function Name : L_round +** +** Purpose : +** +** Round the lower 16 bits of the 32 bit input number into its MS 16 bits +** with saturation. Shift the resulting bits right by 16 and return the 16 +** bit number: +** L_round(L_var1) = extract_h(L_add(L_var1,32768)) +** +** Complexity weight : 1 +** +** Inputs : +** +** L_var1 +** 32 bit long signed integer (Word32 ) whose value falls in the +** range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +L_round (Word32 L_var1) +{ + Word16 var_out; + Word32 L_arrondi; + + L_arrondi = L_add (L_var1, (Word32) 0x00008000L); + var_out = extract_h (L_arrondi); + return (var_out); +} + + +/* +** +** Function Name : L_mac +** +** Purpose : +** +** Multiply var1 by var2 and shift the result left by 1. Add the 32 bit +** result to L_var3 with saturation, return a 32 bit result: +** L_mac(L_var3,var1,var2) = L_add(L_var3,(L_mult(var1,var2)). +** +** Complexity weight : 1 +** +** Inputs : +** +** L_var3 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_mac (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult (var1, var2); + L_var_out = L_add (L_var3, L_produit); + return (L_var_out); +} + + +/* +** +** Function Name : L_msu +** +** Purpose : +** +** Multiply var1 by var2 and shift the result left by 1. Subtract the 32 +** bit result to L_var3 with saturation, return a 32 bit result: +** L_msu(L_var3,var1,var2) = L_sub(L_var3,(L_mult(var1,var2)). +** +** Complexity weight : 1 +** +** Inputs : +** +** L_var3 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_msu (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult (var1, var2); + L_var_out = L_sub (L_var3, L_produit); + return (L_var_out); +} + +/* +** +** Function Name : L_add +** +** Purpose : +** +** 32 bits addition of the two 32 bits variables (L_var1+L_var2) with +** overflow control and saturation; the result is set at +214783647 when +** overflow occurs or at -214783648 when underflow occurs. +** +** Complexity weight : 2 +** +** Inputs : +** +** L_var1 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** L_var2 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_add (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) == 0L) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + } + } + return (L_var_out); +} + +/* +** +** Function Name : L_sub +** +** Purpose : +** +** 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with +** overflow control and saturation; the result is set at +214783647 when +** overflow occurs or at -214783648 when underflow occurs. +** +** Complexity weight : 2 +** +** Inputs : +** +** L_var1 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** L_var2 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_sub (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0L) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + } + } + return (L_var_out); +} + +/* +** +** Function Name : L_negate +** +** Purpose : +** +** Negate the 32 bit variable L_var1 with saturation; saturate in the case +** where input is -2147483648 (0x8000 0000). +** +** Complexity weight : 2 +** +** Inputs : +** +** L_var1 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_negate (Word32 L_var1) +{ + Word32 L_var_out; + + L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1; + return (L_var_out); +} + +/* +** +** Function Name : mult_r +** +** Purpose : +** +** Same as mult with rounding, i.e.: +** mult_r(var1,var2) = shr(((var1*var2) + 16384),15) and +** mult_r(-32768,-32768) = 32767. +** +** Complexity weight : 2 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +mult_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_produit_arr; + + L_produit_arr = (Word32) var1 *(Word32) var2; /* product */ + L_produit_arr += (Word32) 0x00004000L; /* round */ + L_produit_arr &= (Word32) 0xffff8000L; + L_produit_arr >>= 15; /* shift */ + + if (L_produit_arr & (Word32) 0x00010000L) { + /* sign extend when necessary */ + L_produit_arr |= (Word32) 0xffff0000L; + } + + var_out = sature (L_produit_arr); + return (var_out); +} + +/* +** +** Function Name : L_shl +** +** Purpose : +** +** Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero +** fill the var2 LSB of the result. If var2 is negative, L_var1 right by +** -var2 arithmetically shift with sign extension. Saturate the result in +** case of underflows or overflows. +** +** Complexity weight : 2 +** +** Inputs : +** +** L_var1 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_shl (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out = 0L; + + if (var2 <= (Word16) 0) { + L_var_out = L_shr (L_var1, (Word16) - var2); + } + else { + for (; var2 > (Word16) 0; var2--) { + if (L_var1 > (Word32) 0X3fffffffL) { + L_var_out = MAX_32; + break; + } + else { + if (L_var1 < (Word32) 0xc0000000L) { + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2L; + L_var_out = L_var1; + } + } + return (L_var_out); +} + + +/* +** +** Function Name : L_shr +** +** Purpose : +** +** Arithmetically shift the 32 bit input L_var1 right var2 positions with +** sign extension. If var2 is negative, arithmetically shift L_var1 left +** by -var2 and zero fill the var2 LSB of the result. Saturate the result +** in case of underflows or overflows. +** +** Complexity weight : 2 +** +** Inputs : +** +** L_var1 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_shr (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 < (Word16) 0) { + L_var_out = L_shl (L_var1, (Word16) - var2); + } + else { + if (var2 >= (Word16) 31) { + L_var_out = (L_var1 < 0L) ? -1L : 0L; + } + else { + if (L_var1 < 0L) { + L_var_out = ~((~L_var1) >> var2); + } + else { + L_var_out = L_var1 >> var2; + } + } + } + return (L_var_out); +} + +/* +** +** Function Name : shr_r +** +** Purpose : +** +** Same as shr(var1,var2) but with rounding. Saturate the result in case of +** underflows or overflows : +** If var2 is greater than zero : +** shr_r(var1,var2) = shr(add(var1,2**(var2-1)),var2) +** If var2 is less than zero : +** shr_r(var1,var2) = shr(var1,var2). +** +** Complexity weight : 2 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word16 +shr_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 > (Word16) 15) { + var_out = (Word16) 0; + } + else { + var_out = shr (var1, var2); + + if (var2 > (Word16) 0) { + if ((var1 & ((Word16) 1 << (var2 - (Word16) 1))) != (Word16) 0) { + var_out++; + } + } + } + return (var_out); +} + +/* +** +** Function Name : mac_r +** +** Purpose : +** +** Multiply var1 by var2 and shift the result left by 1. Add the 32 bit +** result to L_var3 with saturation. Round the LS 16 bits of the result +** into the MS 16 bits with saturation and shift the result right by 16. +** Return a 16 bit result. +** mac_r(L_var3,var1,var2) = round(L_mac(Lvar3,var1,var2)) +** +** Complexity weight : 2 +** +** Inputs : +** +** L_var3 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. +** +*/ + +Word16 +mac_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_mac (L_var3, var1, var2); + L_var3 = L_add (L_var3, (Word32) 0x00008000L); + var_out = extract_h (L_var3); + return (var_out); +} + + +/* +** +** Function Name : msu_r +** +** Purpose : +** +** Multiply var1 by var2 and shift the result left by 1. Subtract the 32 +** bit result to L_var3 with saturation. Round the LS 16 bits of the res- +** ult into the MS 16 bits with saturation and shift the result right by +** 16. Return a 16 bit result. +** msu_r(L_var3,var1,var2) = round(L_msu(Lvar3,var1,var2)) +** +** Complexity weight : 2 +** +** Inputs : +** +** L_var3 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. +** +*/ + +Word16 +msu_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_msu (L_var3, var1, var2); + L_var3 = L_add (L_var3, (Word32) 0x00008000L); + var_out = extract_h (L_var3); + return (var_out); +} + + + +/* +** +** Function Name : L_deposit_h +** +** Purpose : +** +** Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The +** 16 LS bits of the output are zeroed. +** +** Complexity weight : 2 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= var_out <= 0x7fff 0000. +** +*/ + +Word32 +L_deposit_h (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 << 16; + return (L_var_out); +} + +/* +** +** Function Name : L_deposit_l +** +** Purpose : +** +** Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The +** 16 MS bits of the output are sign extended. +** +** Complexity weight : 2 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0xFFFF 8000 <= var_out <= 0x0000 7fff. +** +*/ + +Word32 +L_deposit_l (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1; + return (L_var_out); +} + +/* +** +** Function Name : L_shr_r +** +** Purpose : +** +** Same as L_shr(L_var1,var2)but with rounding. Saturate the result in case +** of underflows or overflows : +** If var2 is greater than zero : +** L_shr_r(var1,var2) = L_shr(L_add(L_var1,2**(var2-1)),var2) +** If var2 is less than zero : +** L_shr_r(var1,var2) = L_shr(L_var1,var2). +** +** Complexity weight : 3 +** +** Inputs : +** +** L_var1 +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= var1 <= 0x7fff ffff. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_shr_r (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 > (Word16) 31) { + L_var_out = 0L; + } + else { + L_var_out = L_shr (L_var1, var2); + if (var2 > (Word16) 0) { + if ((L_var1 & (1L << (Word16) (var2 - (Word16) 1))) != 0L) { + L_var_out++; + } + } + } + return (L_var_out); +} + +/* +** +** Function Name : L_abs +** +** Purpose : +** +** Absolute value of L_var1; Saturate in case where the input is +** -214783648 +** +** Complexity weight : 3 +** +** Inputs : +** +** L_var1 +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= var1 <= 0x7fff ffff. +** +** Outputs : +** +** none +** +** Return Value : +** +** L_var_out +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x0000 0000 <= var_out <= 0x7fff ffff. +** +*/ + +Word32 +L_abs (Word32 L_var1) +{ + Word32 L_var_out; + + if (L_var1 == MIN_32) { + L_var_out = MAX_32; + } + else { + if (L_var1 < 0L) { + L_var_out = -L_var1; + } + else { + L_var_out = L_var1; + } + } + + return (L_var_out); +} + +/* +** +** Function Name : norm_s +** +** Purpose : +** +** Produces the number of left shift needed to normalize the 16 bit varia- +** ble var1 for positive values on the interval with minimum of 16384 and +** maximum of 32767, and for negative values on the interval with minimum +** of -32768 and maximum of -16384; in order to normalize the result, the +** following operation must be done : +** norm_var1 = shl(var1,norm_s(var1)). +** +** Complexity weight : 15 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0xffff 8000 <= var1 <= 0x0000 7fff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0x0000 0000 <= var_out <= 0x0000 000f. +** +*/ + +Word16 +norm_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == (Word16) 0) { + var_out = (Word16) 0; + } + else { + if (var1 == (Word16) 0xffff) { + var_out = (Word16) 15; + } + else { + if (var1 < (Word16) 0) { + var1 = ~var1; + } + + for (var_out = (Word16) 0; var1 < (Word16) 0x4000; var_out++) { + var1 <<= 1; + } + } + } + + return (var_out); +} + + +/* +** +** Function Name : div_s +** +** Purpose : +** +** Produces a result which is the fractional integer division of var1 by +** var2; var1 and var2 must be positive and var2 must be greater or equal +** to var1; the result is positive (leading bit equal to 0) and truncated +** to 16 bits. +** If var1 = var2 then div(var1,var2) = 32767. +** +** Complexity weight : 18 +** +** Inputs : +** +** var1 +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0x0000 0000 <= var1 <= var2 and var2 != 0. +** +** var2 +** 16 bit short signed integer (Word16) whose value falls in the +** range : var1 <= var2 <= 0x0000 7fff and var2 != 0. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0x0000 0000 <= var_out <= 0x0000 7fff. +** It's a Q15 value (point between b15 and b14). +*/ + +Word16 +div_s (Word16 var1, Word16 var2) +{ + Word16 var_out = (Word16) 0; + Word16 iteration; + Word32 L_num; + Word32 L_denom; + + if ((var1 > var2) || (var1 < (Word16) 0) || (var2 < (Word16) 0)) { + printf ("Division Error\n"); + exit (0); + } + + if (var2 == (Word16) 0) { + printf ("Division by 0, Fatal error \n"); + exit (0); + } + + if (var1 == (Word16) 0) { + var_out = (Word16) 0; + } + else { + if (var1 == var2) { + var_out = MAX_16; + } + else { + L_num = L_deposit_l (var1); + L_denom = L_deposit_l (var2); + + for (iteration = (Word16) 0; iteration < (Word16) 15; iteration++) { + var_out <<= 1; + L_num <<= 1; + + if (L_num >= L_denom) { + L_num = L_sub (L_num, L_denom); + var_out = add (var_out, (Word16) 1); + } + } + } + } + + return (var_out); +} + + +/* +** +** Function Name : norm_l +** +** Purpose : +** +** Produces the number of left shift needed to normalize the 32 bit varia- +** ble l_var1 for positive values on the interval with minimum of +** 1073741824 and maximum of 2147483647, and for negative values on the in- +** terval with minimum of -2147483648 and maximum of -1073741824; in order +** to normalize the result, the following operation must be done : +** norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). +** +** Complexity weight : 30 +** +** Inputs : +** +** L_var1 +** 32 bit long signed integer (Word32) whose value falls in the +** range : 0x8000 0000 <= var1 <= 0x7fff ffff. +** +** Outputs : +** +** none +** +** Return Value : +** +** var_out +** 16 bit short signed integer (Word16) whose value falls in the +** range : 0x0000 0000 <= var_out <= 0x0000 001f. +*/ + +Word16 +norm_l (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 == 0L) { + var_out = (Word16) 0; + } + else { + if (L_var1 == (Word32) 0xffffffffL) { + var_out = (Word16) 31; + } + else { + if (L_var1 < 0L) { + L_var1 = ~L_var1; + } + + for (var_out = (Word16) 0; L_var1 < (Word32) 0x40000000L; var_out++) { + L_var1 <<= 1L; + } + } + } + + return (var_out); +} + +/* + Additional operators +*/ +Word32 +L_mls (Word32 Lv, Word16 v) +{ + Word32 Temp; + + Temp = Lv & (Word32) 0x0000ffff; + Temp = Temp * (Word32) v; + Temp = L_shr (Temp, (Word16) 15); + Temp = L_mac (Temp, v, extract_h (Lv)); + + return Temp; +} + +/* +| +| Function Name : div_l +| +| Purpose : +| +| Produces a result which is the fractional integer division of L_var1 by +| var2; L_var1 and var2 must be positive and var2 << 16 must be greater or +| equal to L_var1; the result is positive (leading bit equal to 0) and +| truncated to 16 bits. +| If L_var1 == var2 << 16 then div_l(L_var1,var2) = 32767. +| +| Complexity weight : 20 +| +| Inputs : +| +| L_var1 +| 32 bit long signed integer (Word32) whose value falls in the +| range : 0x0000 0000 <= var1 <= (var2 << 16) and var2 != 0. +| L_var1 must be considered as a Q.31 value +| +| var2 +| 16 bit short signed integer (Word16) whose value falls in the +| range : var1 <= (var2<< 16) <= 0x7fff0000 and var2 != 0. +| var2 must be considered as a Q.15 value +| +| Outputs : +| +| none +| +| Return Value : +| +| var_out +| 16 bit short signed integer (Word16) whose value falls in the +| range : 0x0000 0000 <= var_out <= 0x0000 7fff. +| It's a Q15 value (point between b15 and b14). +*/ + + +Word16 +div_l (Word32 L_num, Word16 den) +{ + + Word16 var_out = (Word16) 0; + Word32 L_den; + Word16 iteration; + + if (den == (Word16) 0) { + printf ("Division by 0 in div_l, Fatal error \n"); + exit (0); + } + + if ((L_num < (Word32) 0) || (den < (Word16) 0)) { + printf ("Division Error in div_l, Fatal error \n"); + exit (0); + } + + L_den = L_deposit_h (den); + + if (L_num >= L_den) { + return MAX_16; + } + else { + L_num = L_shr (L_num, (Word16) 1); + L_den = L_shr (L_den, (Word16) 1); + for (iteration = (Word16) 0; iteration < (Word16) 15; iteration++) { + var_out = shl (var_out, (Word16) 1); + L_num = L_shl (L_num, (Word16) 1); + if (L_num >= L_den) { + L_num = L_sub (L_num, L_den); + var_out = add (var_out, (Word16) 1); + } + } + + return var_out; + } +} + +/* +** Function i_mult() * +** ~~~~~~~~~~~~~~~~~ * +** Integer multiplication. * +** +*/ + +Word16 +i_mult (Word16 a, Word16 b) +{ + return a * b; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/basop.h asterisk-1.2.1/codecs/g723_1/basop.h --- asterisk-1.2.1.ori/codecs/g723_1/basop.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/basop.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,38 @@ +#define MAX_32 (Word32)0x7fffffffL +#define MIN_32 (Word32)0x80000000L + +#define MAX_16 (Word16)0x7fff +#define MIN_16 (Word16)0x8000 + +Word16 add (Word16 var1, Word16 var2); /* Short add, 1 */ +Word16 sub (Word16 var1, Word16 var2); /* Short sub, 1 */ +Word16 abs_s (Word16 var1); /* Short abs, 1 */ +Word16 shl (Word16 var1, Word16 var2); /* Short shift left, 1 */ +Word16 shr (Word16 var1, Word16 var2); /* Short shift right, 1 */ +Word16 mult (Word16 var1, Word16 var2); /* Short mult, 1 */ +Word32 L_mult (Word16 var1, Word16 var2); /* Long mult, 1 */ +Word16 negate (Word16 var1); /* Short negate, 1 */ +Word16 extract_h (Word32 L_var1); /* Extract high, 1 */ +Word16 extract_l (Word32 L_var1); /* Extract low, 1 */ +Word16 L_round (Word32 L_var1); /* Round, 1 */ +Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); /* Mac, 1 */ +Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); /* Msu, 1 */ +Word32 L_add (Word32 L_var1, Word32 L_var2); /* Long add, 2 */ +Word32 L_sub (Word32 L_var1, Word32 L_var2); /* Long sub, 2 */ +Word32 L_negate (Word32 L_var1); /* Long negate, 2 */ +Word16 mult_r (Word16 var1, Word16 var2); /* Mult with round, 2 */ +Word32 L_shl (Word32 L_var1, Word16 var2); /* Long shift left, 2 */ +Word32 L_shr (Word32 L_var1, Word16 var2); /* Long shift right, 2 */ +Word16 shr_r (Word16 var1, Word16 var2); /* Shift right with round, 2 */ +Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); /* Mac with rounding, 2 */ +Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); /* Msu with rounding, 2 */ +Word32 L_deposit_h (Word16 var1); /* 16 bit var1 -> MSB, 2 */ +Word32 L_deposit_l (Word16 var1); /* 16 bit var1 -> LSB, 2 */ +Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with round, 3 */ +Word32 L_abs (Word32 L_var1); /* Long abs, 3 */ +Word16 norm_s (Word16 var1); /* Short norm, 15 */ +Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */ +Word16 norm_l (Word32 L_var1); /* Long norm, 30 */ +Word32 L_mls (Word32, Word16); +Word16 div_l (Word32, Word16); +Word16 i_mult (Word16 a, Word16 b); diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/cod_cng.c asterisk-1.2.1/codecs/g723_1/cod_cng.c --- asterisk-1.2.1.ori/codecs/g723_1/cod_cng.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/cod_cng.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,487 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** +** File: "cod_cng.c" +** +** Description: Comfort noise generation +** performed at the encoder part +** +** Functions: Init_Cod_Cng() +** Cod_Cng() +** Update_Cng() +** +** Local functions: +** ComputePastAvFilter() +** CalcRC() +** LpcDiff() +** +** +*/ + +#include +#include + +#include "typedef.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "util_lbc.h" +#include "basop.h" +#include "lsp.h" +#include "lpc.h" +#include "util_cng.h" +#include "cod_cng.h" +#include "vad.h" +#include "coder.h" +/* Declaration of local functions */ +static void ComputePastAvFilter (CODSTATDEF * CodStat, Word16 * Coeff); +static void CalcRC (Word16 * Coeff, Word16 * RC, Word16 * shRC); +static Flag LpcDiff (Word16 * RC, Word16 shRC, Word16 * Acf, Word16 alpha); + +/* +** +** Function: Init_Cod_Cng() +** +** Description: Initialize Cod_Cng static variables +** +** Links to text: +** +** Arguments: None +** +** Outputs: None +** +** Return value: None +** +*/ +void +Init_Cod_Cng (CODSTATDEF * CodStat) +{ + int i; + + CodStat->CurGain = 0; + + for (i = 0; i < SizAcf; i++) + CodStat->Acf[i] = 0; + + for (i = 0; i <= NbAvAcf; i++) + CodStat->ShAcf[i] = 40; + + for (i = 0; i < LpcOrder; i++) + CodStat->SidLpc[i] = 0; + + CodStat->PastFtyp = 1; + + CodStat->RandSeed = 12345; + + return; +} + + +/* +** +** Function: Cod_Cng() +** +** Description: Computes Ftyp for inactive frames +** 0 : for untransmitted frames +** 2 : for SID frames +** Computes current frame excitation +** Computes current frame LSPs +** Computes the coded parameters of SID frames +** +** Links to text: +** +** Arguments: +** +** Word16 *DataExc Current frame synthetic excitation +** Word16 *Ftyp Characterizes the frame type for CNG +** LINEDEF *Line Quantized parameters (used for SID frames) +** Word16 *QntLpc Interpolated frame LPC coefficients +** +** Outputs: +** +** Word16 *DataExc +** Word16 *Ftyp +** LINEDEF *Line +** Word16 *QntLpc +** +** Return value: None +** +*/ +void +Cod_Cng (CODSTATDEF * CodStat, Word16 * DataExc, Word16 * Ftyp, + LINEDEF * Line, Word16 * QntLpc) +{ + + + Word16 curCoeff[LpcOrder]; + Word16 curQGain; + Word16 temp; + int i; + + /* + * Update Ener + */ + for (i = NbAvGain - 1; i >= 1; i--) { + CodStat->Ener[i] = CodStat->Ener[i - 1]; + } + + /* + * Compute LPC filter of present frame + */ + CodStat->Ener[0] = + Durbin (curCoeff, &CodStat->Acf[1], CodStat->Acf[0], &temp); + + /* + * if first frame of silence => SID frame + */ + if (CodStat->PastFtyp == 1) { + *Ftyp = 2; + CodStat->NbEner = 1; + curQGain = Qua_SidGain (CodStat->Ener, CodStat->ShAcf, CodStat->NbEner); + } + + else { + CodStat->NbEner++; + if (CodStat->NbEner > NbAvGain) + CodStat->NbEner = NbAvGain; + curQGain = Qua_SidGain (CodStat->Ener, CodStat->ShAcf, CodStat->NbEner); + + /* + * Compute stationarity of current filter + * versus reference filter + */ + if (LpcDiff (CodStat->RC, CodStat->ShRC, CodStat->Acf, *CodStat->Ener) == + 0) { + /* transmit SID frame */ + *Ftyp = 2; + } + else { + temp = abs_s (sub (curQGain, CodStat->IRef)); + if (temp > ThreshGain) { + *Ftyp = 2; + } + else { + /* no transmission */ + *Ftyp = 0; + } + } + } + + /* + * If SID frame : Compute SID filter + */ + if (*Ftyp == 2) { + + /* + * Evaluates local stationnarity : + * Computes difference between current filter and past average filter + * if signal not locally stationary SID filter = current filter + * else SID filter = past average filter + */ + /* Compute past average filter */ + ComputePastAvFilter (CodStat, CodStat->SidLpc); + + /* If adaptation enabled, fill noise filter */ + if (!CodStat->Aen) { + for (i = 0; i < LpcOrder; i++) + CodStat->NLpc[i] = CodStat->SidLpc[i]; + } + + /* Compute autocorr. of past average filter coefficients */ + CalcRC (CodStat->SidLpc, CodStat->RC, &CodStat->ShRC); + + if (LpcDiff (CodStat->RC, CodStat->ShRC, CodStat->Acf, *CodStat->Ener) == + 0) { + for (i = 0; i < LpcOrder; i++) { + CodStat->SidLpc[i] = curCoeff[i]; + } + CalcRC (curCoeff, CodStat->RC, &CodStat->ShRC); + } + + /* + * Compute SID frame codes + */ + /* Compute LspSid */ + AtoLsp (CodStat->LspSid, CodStat->SidLpc, CodStat->PrevLsp); + Line->LspId = Lsp_Qnt (CodStat->LspSid, CodStat->PrevLsp); + Lsp_Inq (CodStat->LspSid, CodStat->PrevLsp, Line->LspId, 0); + + Line->Sfs[0].Mamp = curQGain; + CodStat->IRef = curQGain; + CodStat->SidGain = Dec_SidGain (CodStat->IRef); + + } /* end of Ftyp=2 case (SID frame) */ + + /* + * Compute new excitation + */ + if (CodStat->PastFtyp == 1) { + CodStat->CurGain = CodStat->SidGain; + } + else { + CodStat->CurGain = extract_h (L_add (L_mult (CodStat->CurGain, 0x7000), + L_mult (CodStat->SidGain, 0x1000))); + } + Calc_Exc_Rand (CodStat->WrkRate, CodStat->CurGain, CodStat->PrevExc, + DataExc, &CodStat->RandSeed, Line); + + /* + * Interpolate LSPs and update PrevLsp + */ + Lsp_Int (QntLpc, CodStat->LspSid, CodStat->PrevLsp); + for (i = 0; i < LpcOrder; i++) { + CodStat->PrevLsp[i] = CodStat->LspSid[i]; + } + + /* + * Output & save frame type info + */ + CodStat->PastFtyp = *Ftyp; + return; +} + +/* +** +** Function: Update_Acf() +** +** Description: Computes & Stores sums of subframe-acfs +** +** Links to text: +** +** Arguments: +** +** Word16 *Acf_sf sets of subframes Acfs of current frame +** Word16 *ShAcf_sf corresponding scaling factors +** +** Output : None +** +** Return value: None +** +*/ +void +Update_Acf (CODSTATDEF * CodStat, Word16 * Acf_sf, Word16 * ShAcf_sf) +{ + + int i, i_subfr; + Word16 *ptr1, *ptr2; + Word32 L_temp[LpcOrderP1]; + Word16 sh1, temp; + Word32 L_acc0; + + /* Update Acf and ShAcf */ + ptr2 = CodStat->Acf + SizAcf; + ptr1 = ptr2 - LpcOrderP1; + for (i = LpcOrderP1; i < SizAcf; i++) + *(--ptr2) = *(--ptr1); + for (i = NbAvAcf; i >= 1; i--) + CodStat->ShAcf[i] = CodStat->ShAcf[i - 1]; + + /* Search ShAcf_sf min for current frame */ + sh1 = ShAcf_sf[0]; + for (i_subfr = 1; i_subfr < SubFrames; i_subfr++) { + if (ShAcf_sf[i_subfr] < sh1) + sh1 = ShAcf_sf[i_subfr]; + } + sh1 = add (sh1, 14); /* 2 bits of margin */ + + /* Compute current sum of acfs */ + for (i = 0; i <= LpcOrder; i++) + L_temp[i] = 0; + + ptr2 = Acf_sf; + for (i_subfr = 0; i_subfr < SubFrames; i_subfr++) { + temp = sub (sh1, ShAcf_sf[i_subfr]); + for (i = 0; i <= LpcOrder; i++) { + L_acc0 = L_deposit_l (*ptr2++); + L_acc0 = L_shl (L_acc0, temp); /* shift right if temp<0 */ + L_temp[i] = L_add (L_temp[i], L_acc0); + } + } + /* Normalize */ + temp = norm_l (L_temp[0]); + temp = sub (16, temp); + if (temp < 0) + temp = 0; + for (i = 0; i <= LpcOrder; i++) { + CodStat->Acf[i] = extract_l (L_shr (L_temp[i], temp)); + } + + CodStat->ShAcf[0] = sub (sh1, temp); + + return; +} + +/* +** +** Function: ComputePastAvFilter() +** +** Description: Computes past average filter +** +** Links to text: +** +** Argument: +** +** Word16 *Coeff set of LPC coefficients +** +** Output: +** +** Word16 *Coeff +** +** Return value: None +** +*/ +void +ComputePastAvFilter (CODSTATDEF * CodStat, Word16 * Coeff) +{ + int i, j; + Word16 *ptr_Acf; + Word32 L_sumAcf[LpcOrderP1]; + Word16 Corr[LpcOrder], Err; + Word16 sh1, temp; + Word32 L_acc0; + + /* Search ShAcf min */ + sh1 = CodStat->ShAcf[1]; + for (i = 2; i <= NbAvAcf; i++) { + temp = CodStat->ShAcf[i]; + if (temp < sh1) + sh1 = temp; + } + sh1 = add (sh1, 14); /* 2 bits of margin : NbAvAcf <= 4 */ + + /* Compute sum of NbAvAcf frame-Acfs */ + for (j = 0; j <= LpcOrder; j++) + L_sumAcf[j] = 0; + + ptr_Acf = CodStat->Acf + LpcOrderP1; + for (i = 1; i <= NbAvAcf; i++) { + temp = sub (sh1, CodStat->ShAcf[i]); + for (j = 0; j <= LpcOrder; j++) { + L_acc0 = L_deposit_l (*ptr_Acf++); + L_acc0 = L_shl (L_acc0, temp); /* shift right if temp<0 */ + L_sumAcf[j] = L_add (L_sumAcf[j], L_acc0); + } + } + + /* Normalize */ + temp = norm_l (L_sumAcf[0]); + temp = sub (16, temp); + if (temp < 0) + temp = 0; + Err = extract_l (L_shr (L_sumAcf[0], temp)); + for (i = 1; i < LpcOrderP1; i++) { + Corr[i - 1] = extract_l (L_shr (L_sumAcf[i], temp)); + } + + Durbin (Coeff, Corr, Err, &temp); + + return; +} + +/* +** +** Function: CalcRC() +** +** Description: Computes function derived from +** the autocorrelation of LPC coefficients +** used for Itakura distance +** +** Links to text: +** +** Arguments : +** +** Word16 *Coeff set of LPC coefficients +** Word16 *RC derived from LPC coefficients autocorrelation +** Word16 *ShRC corresponding scaling factor +** +** Outputs : +** +** Word16 *RC +** Word16 *ShRC +** +** Return value: None +** +*/ +void +CalcRC (Word16 * Coeff, Word16 * RC, Word16 * ShRC) +{ + int i, j; + Word16 sh1; + Word32 L_acc; + + L_acc = 0L; + for (j = 0; j < LpcOrder; j++) { + L_acc = L_mac (L_acc, Coeff[j], Coeff[j]); + } + L_acc = L_shr (L_acc, 1); + L_acc = L_add (L_acc, 0x04000000L); /* 1 << 2 * Lpc_justif. */ + sh1 = norm_l (L_acc) - (Word16) 2; /* 1 bit because of x2 in RC[i], i> 0 */ + /* & 1 bit margin for Itakura distance */ + L_acc = L_shl (L_acc, sh1); /* shift right if < 0 */ + RC[0] = L_round (L_acc); + + for (i = 1; i <= LpcOrder; i++) { + L_acc = L_mult ((Word16) 0xE000, Coeff[i - 1]); /* - (1 << Lpc_justif.) */ + for (j = 0; j < LpcOrder - i; j++) { + L_acc = L_mac (L_acc, Coeff[j], Coeff[j + i]); + } + L_acc = L_shl (L_acc, sh1); + RC[i] = L_round (L_acc); + } + *ShRC = sh1; + return; +} + +/* +** +** Function: LpcDiff() +** +** Description: Comparison of two filters +** using Itakura distance +** 1st filter : defined by *ptrAcf +** 2nd filter : defined by *RC +** the autocorrelation of LPC coefficients +** used for Itakura distance +** +** Links to text: +** +** Arguments : +** +** Word16 *RC derived from LPC coefficients autocorrelation +** Word16 ShRC corresponding scaling factor +** Word16 *ptrAcf pointer on signal autocorrelation function +** Word16 alpha residual energy in LPC analysis using *ptrAcf +** +** Output: None +** +** Return value: flag = 1 if similar filters +** flag = 0 if different filters +** +*/ +Flag +LpcDiff (Word16 * RC, Word16 ShRC, Word16 * ptrAcf, Word16 alpha) +{ + Word32 L_temp0, L_temp1; + Word16 temp; + int i; + Flag diff; + + L_temp0 = 0L; + for (i = 0; i <= LpcOrder; i++) { + temp = shr (ptrAcf[i], 2); /* + 2 margin bits */ + L_temp0 = L_mac (L_temp0, RC[i], temp); + } + + temp = mult_r (alpha, FracThresh); + L_temp1 = L_add ((Word32) temp, (Word32) alpha); + temp = add (ShRC, 9); /* 9 = Lpc_justif. * 2 - 15 - 2 */ + L_temp1 = L_shl (L_temp1, temp); + + if (L_temp0 < L_temp1) + diff = 1; + else + diff = 0; + return (diff); +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/cod_cng.h asterisk-1.2.1/codecs/g723_1/cod_cng.h --- asterisk-1.2.1.ori/codecs/g723_1/cod_cng.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/cod_cng.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,18 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** +** File: "cod_cng.h" +** +** Description: Function prototypes for "cod_cng.c" +** +*/ + +#include "coder.h" + +void Init_Cod_Cng (CODSTATDEF * CodStat); +void Cod_Cng (CODSTATDEF * CodStat, Word16 * DataExc, Word16 * Ftyp, + LINEDEF * Line, Word16 * QntLpc); +void Update_Acf (CODSTATDEF * CodStat, Word16 * Acfsf, Word16 * Shsf); diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/coder.c asterisk-1.2.1/codecs/g723_1/coder.c --- asterisk-1.2.1.ori/codecs/g723_1/coder.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/coder.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,302 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "coder.c" +** +** Description: Top-level source code for G.723 dual-rate coder +** +** Functions: Init_Coder() +** Coder() +** +** +*/ + + +#include +#include +#include + +#include "typedef.h" +#include "basop.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "coder.h" +#include "lpc.h" +#include "lsp.h" +#include "exc_lbc.h" +#include "util_lbc.h" +#include "vad.h" +#include "cod_cng.h" +#include "tame.h" +/* +** +** Function: Init_Coder() +** +** Description: Initializes non-zero state variables +** for the coder. +** +** Links to text: Section 2.21 +** +** Arguments: None +** +** Outputs: +** +** Return value: None +** +** CODSTATDEF *CodStat codec status +** +*/ +CODSTATDEF * +Init_Coder (Flag UseVx, Flag UseHp, enum Crate WrkRate) +{ + CODSTATDEF *CodStat; + int i; + + CodStat = (CODSTATDEF *) malloc (sizeof (CODSTATDEF)); + /* Initialize encoder data structure with zeros */ + memset (CodStat, 0, sizeof (CODSTATDEF)); + + /* Initialize the previously decoded LSP vector to the DC vector */ + for (i = 0; i < LpcOrder; i++) + CodStat->PrevLsp[i] = LspDcTable[i]; + + /* Initialize the taming procedure */ + for (i = 0; i < SizErr; i++) + CodStat->Err[i] = Err0; + + + CodStat->UseVx = UseVx; + CodStat->UseHp = UseHp; + CodStat->WrkRate = WrkRate; + + if (UseVx) { + Init_Vad (CodStat); + Init_Cod_Cng (CodStat); + } + + return CodStat; +} + +/* +** +** Function: Coder() +** +** Description: Implements G.723 dual-rate coder for a frame +** of speech +** +** Links to text: Section 2 +** +** Arguments: +** +** Word16 DataBuff[] frame (480 bytes) +** + +** Outputs: +** +** Word16 Vout[] Encoded frame (20/24 bytes) +** +** Return value: +** +** Flag Always True +** +*/ +Flag +Coder (CODSTATDEF * CodStat, Word16 * DataBuff, char *Vout) +{ + int i, j; + + /* + Local variables + */ + Word16 UnqLpc[SubFrames * LpcOrder]; + Word16 QntLpc[SubFrames * LpcOrder]; + Word16 PerLpc[2 * SubFrames * LpcOrder]; + + Word16 LspVect[LpcOrder]; + LINEDEF Line; + PWDEF Pw[SubFrames]; + + Word16 ImpResp[SubFrLen]; + + Word16 *Dpnt; + + Word16 Ftyp = 1; + + /* + Coder Start + */ + Line.Crc = (Word16) 0; + + Rem_Dc (CodStat, DataBuff); + + /* Compute the Unquantized Lpc set for whole frame */ + Comp_Lpc (CodStat, UnqLpc, CodStat->PrevDat, DataBuff); + + /* Convert to Lsp */ + AtoLsp (LspVect, &UnqLpc[LpcOrder * (SubFrames - 1)], CodStat->PrevLsp); + + /* Compute the Vad */ + Ftyp = (Word16) Comp_Vad (CodStat, DataBuff); + + /* VQ Lsp vector */ + Line.LspId = Lsp_Qnt (LspVect, CodStat->PrevLsp); + + Mem_Shift (CodStat->PrevDat, DataBuff); + + /* Compute Perceptual filter Lpc coefficients */ + Wght_Lpc (PerLpc, UnqLpc); + + /* Apply the perceptual weighting filter */ + Error_Wght (CodStat, DataBuff, PerLpc); + + /* + // Compute Open loop pitch estimates + */ + Dpnt = (Word16 *) malloc (sizeof (Word16) * (PitchMax + Frame)); + + /* Construct the buffer */ + for (i = 0; i < PitchMax; i++) + Dpnt[i] = CodStat->PrevWgt[i]; + for (i = 0; i < Frame; i++) + Dpnt[PitchMax + i] = DataBuff[i]; + + Vec_Norm (Dpnt, (Word16) (PitchMax + Frame)); + + j = PitchMax; + for (i = 0; i < SubFrames / 2; i++) { + Line.Olp[i] = Estim_Pitch (Dpnt, (Word16) j); + CodStat->Polp[i + 2] = Line.Olp[i]; + j += 2 * SubFrLen; + } + + if (Ftyp != 1) { + + /* + // Case of inactive signal + */ + free ((char *) Dpnt); + + /* Save PrevWgt */ + for (i = 0; i < PitchMax; i++) + CodStat->PrevWgt[i] = DataBuff[i + Frame - PitchMax]; + + + + /* CodCng => Ftyp = 0 (untransmitted) or 2 (SID) */ + Cod_Cng (CodStat, DataBuff, &Ftyp, &Line, QntLpc); + + /* Update the ringing delays */ + Dpnt = DataBuff; + for (i = 0; i < SubFrames; i++) { + + /* Update exc_err */ + Update_Err (CodStat, Line.Olp[i >> 1], Line.Sfs[i].AcLg, + Line.Sfs[i].AcGn); + + Upd_Ring (CodStat, Dpnt, &QntLpc[i * LpcOrder], + &PerLpc[i * 2 * LpcOrder], CodStat->PrevErr); + Dpnt += SubFrLen; + } + } + + else { + + /* + // Case of Active signal (Ftyp=1) + */ + + /* Compute the Hmw */ + j = PitchMax; + for (i = 0; i < SubFrames; i++) { + Pw[i] = Comp_Pw (Dpnt, (Word16) j, Line.Olp[i >> 1]); + j += SubFrLen; + } + + /* Reload the buffer */ + for (i = 0; i < PitchMax; i++) + Dpnt[i] = CodStat->PrevWgt[i]; + for (i = 0; i < Frame; i++) + Dpnt[PitchMax + i] = DataBuff[i]; + + /* Save PrevWgt */ + for (i = 0; i < PitchMax; i++) + CodStat->PrevWgt[i] = Dpnt[Frame + i]; + + /* Apply the Harmonic filter */ + j = 0; + for (i = 0; i < SubFrames; i++) { + Filt_Pw (DataBuff, Dpnt, (Word16) j, Pw[i]); + j += SubFrLen; + } + free ((char *) Dpnt); + + /* Inverse quantization of the LSP */ + Lsp_Inq (LspVect, CodStat->PrevLsp, Line.LspId, Line.Crc); + + /* Interpolate the Lsp vectors */ + Lsp_Int (QntLpc, LspVect, CodStat->PrevLsp); + + /* Copy the LSP vector for the next frame */ + for (i = 0; i < LpcOrder; i++) + CodStat->PrevLsp[i] = LspVect[i]; + + /* + // Start the sub frame processing loop + */ + Dpnt = DataBuff; + + for (i = 0; i < SubFrames; i++) { + + /* Compute full impulse response */ + Comp_Ir (ImpResp, &QntLpc[i * LpcOrder], + &PerLpc[i * 2 * LpcOrder], Pw[i]); + + /* Subtract the ringing of previous sub-frame */ + Sub_Ring (CodStat, Dpnt, &QntLpc[i * LpcOrder], + &PerLpc[i * 2 * LpcOrder], CodStat->PrevErr, Pw[i]); + + /* Compute adaptive code book contribution */ + Find_Acbk (CodStat, Dpnt, ImpResp, CodStat->PrevExc, &Line, (Word16) i); + + /* Compute fixed code book contribution */ + Find_Fcbk (CodStat->WrkRate, Dpnt, ImpResp, &Line, (Word16) i); + + /* Reconstruct the excitation */ + Decod_Acbk (CodStat->WrkRate, ImpResp, CodStat->PrevExc, + Line.Olp[i >> 1], Line.Sfs[i].AcLg, Line.Sfs[i].AcGn); + + for (j = SubFrLen; j < PitchMax; j++) + CodStat->PrevExc[j - SubFrLen] = CodStat->PrevExc[j]; + + for (j = 0; j < SubFrLen; j++) { + Dpnt[j] = shl (Dpnt[j], (Word16) 1); + Dpnt[j] = add (Dpnt[j], ImpResp[j]); + CodStat->PrevExc[PitchMax - SubFrLen + j] = Dpnt[j]; + } + + /* Update exc_err */ + Update_Err (CodStat, Line.Olp[i >> 1], Line.Sfs[i].AcLg, + Line.Sfs[i].AcGn); + + /* Update the ringing delays */ + Upd_Ring (CodStat, Dpnt, &QntLpc[i * LpcOrder], + &PerLpc[i * 2 * LpcOrder], CodStat->PrevErr); + + Dpnt += SubFrLen; + } /* end of subframes loop */ + + /* + // Save Vad information and reset CNG random generator + */ + CodStat->PastFtyp = 1; + CodStat->RandSeed = 12345; + + } /* End of active frame case */ + + /* Pack the Line structure */ + Line_Pack (CodStat->WrkRate, &Line, Vout, Ftyp); + + return (Flag) True; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/coder.h asterisk-1.2.1/codecs/g723_1/coder.h --- asterisk-1.2.1.ori/codecs/g723_1/coder.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/coder.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,85 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "coder.h" +** +** Description: Function prototypes and external declarations +** for "coder.c" +** +*/ + +#ifndef _CODEC_H_ +#define _CODEC_H_ + +#include "cst_lbc.h" + +typedef struct +{ + /* High pass variables */ + Word16 HpfZdl; + Word32 HpfPdl; + + /* Sine wave detector */ + Word16 SinDet; + + /* Lsp previous vector */ + Word16 PrevLsp[LpcOrder]; + + /* All pitch operation buffers */ + Word16 PrevWgt[PitchMax]; + Word16 PrevErr[PitchMax]; + Word16 PrevExc[PitchMax]; + + /* Required memory for the delay */ + Word16 PrevDat[LpcFrame - SubFrLen]; + + /* Used delay lines */ + Word16 WghtFirDl[LpcOrder]; + Word16 WghtIirDl[LpcOrder]; + Word16 RingFirDl[LpcOrder]; + Word16 RingIirDl[LpcOrder]; + + /* Taming procedure errors */ + Word32 Err[SizErr]; + + + /* COD_CNG */ + + Word16 CurGain; + Word16 PastFtyp; + Word16 Acf[SizAcf]; + Word16 ShAcf[NbAvAcf + 1]; + Word16 LspSid[LpcOrder]; + Word16 SidLpc[LpcOrder]; + Word16 RC[LpcOrderP1]; + Word16 ShRC; + Word16 Ener[NbAvGain]; + Word16 NbEner; + Word16 IRef; + Word16 SidGain; + Word16 RandSeed; + + /* Vad */ + Word16 Hcnt; + Word16 Vcnt; + Word32 Penr; + Word32 Nlev; + Word16 Aen; + Word16 Polp[4]; + Word16 NLpc[LpcOrder]; + + + /* Flags */ + + Flag UseVx; + Flag UseHp; + enum Crate WrkRate; + +} CODSTATDEF; + +CODSTATDEF *Init_Coder (Flag UseVx, Flag UseHp, enum Crate WrkRate); +Flag Coder (CODSTATDEF * CodeStat, Word16 * DataBuff, char *Vout); + +#endif /* _CODEC_H_ */ diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/cst_lbc.h asterisk-1.2.1/codecs/g723_1/cst_lbc.h --- asterisk-1.2.1.ori/codecs/g723_1/cst_lbc.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/cst_lbc.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,146 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "cst_lbc.h" +** +** Description: This file contains global definition of the SG15 +** LBC Coder for 6.3/5.3 kbps. +** +*/ + +#ifndef _CST_LBC_H_ +#define _CST_LBC_H_ + +#define False 0 +#define True 1 + +/* Definition of the working mode */ +enum Wmode +{ Both, Cod, Dec }; + +/* Coder rate */ +enum Crate +{ Rate63, Rate53 }; + +/* Coder global constants */ +#define Frame 240 +#define LpcFrame 180 +#define SubFrames 4 +#define SubFrLen (Frame/SubFrames) + +/* LPC constants */ +#define LpcOrder 10 +#define RidgeFact 10 +#define CosineTableSize 512 +#define PreCoef (Word16) 0xc000 /* -0.25*2 */ + +#define LspPrd0 12288 +#define LspPrd1 23552 + +#define LspQntBands 3 +#define LspCbSize 256 +#define LspCbBits 8 + +/* LTP constants */ +#define PitchMin 18 +#define PitchMax (PitchMin+127) +#define PwConst (Word16) 0x2800 +#define PwRange 3 +#define ClPitchOrd 5 +#define Pstep 1 +#define NbFilt085 85 +#define NbFilt170 170 + +/* MP-MLQ constants */ +#define Sgrid 2 +#define MaxPulseNum 6 +#define MlqSteps 2 + +/* acelp constants */ +#define SubFrLen2 (SubFrLen +4) +#define DIM_RR 416 +#define NB_POS 8 +#define STEP 8 +#define MSIZE 64 +#define threshold 16384 /* 0.5 = 16384 in Q15 */ +#define max_time 120 + +/* Gain constant */ +#define NumOfGainLev 24 + +/* FER constant */ +#define ErrMaxNum 3 + +/* CNG constants */ +#define NbAvAcf 3 /* Nb of frames for Acf average */ +#define NbAvGain 3 /* Nb of frames for gain average */ +#define ThreshGain 3 /* Theshold for quantized gains */ +#define FracThresh 7000 /* Itakura dist threshold: frac. part */ +#define NbPulsBlk 11 /* Nb of pulses in 2-subframes blocks */ + +#define InvNbPulsBlk 2979 /* 32768/NbPulsBlk */ +#define NbFilt 50 /* number of filters for CNG exc generation */ +#define LpcOrderP1 (LpcOrder+1) +#define SizAcf ((NbAvAcf+1)*LpcOrderP1) /* size of array Acf */ +#define SubFrLenD (2*SubFrLen) +#define Gexc_Max 5000 /* Maximum gain for fixed CNG excitation */ + +/* Taming constants */ +#define NbFilt085_min 51 +#define NbFilt170_min 93 +#define SizErr 5 +#define Err0 (Word32)4 /* scaling factor */ +#define ThreshErr 0x40000000L +#define DEC (30 - 7) + + /* subframe coded parameters */ +typedef struct +{ + Word16 AcLg; + Word16 AcGn; + Word16 Mamp; + Word16 Grid; + Word16 Tran; + Word16 Pamp; + Word32 Ppos; +} SFSDEF; + + /* frame coded parameters */ +typedef struct +{ + Word16 Crc; + Word32 LspId; + Word16 Olp[SubFrames / 2]; + SFSDEF Sfs[SubFrames]; +} LINEDEF; + + /* harmonic noise shaping filter parameters */ +typedef struct +{ + Word16 Indx; + Word16 Gain; +} PWDEF; + + /* pitch postfilter parameters */ +typedef struct +{ + Word16 Indx; + Word16 Gain; + Word16 ScGn; +} PFDEF; + + /* best excitation vector parameters for the high rate */ +typedef struct +{ + Word32 MaxErr; + Word16 GridId; + Word16 MampId; + Word16 UseTrn; + Word16 Ploc[MaxPulseNum]; + Word16 Pamp[MaxPulseNum]; +} BESTDEF; + + +#endif diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/decod.c asterisk-1.2.1/codecs/g723_1/decod.c --- asterisk-1.2.1.ori/codecs/g723_1/decod.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/decod.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,382 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "decod.c" +** +** Description: Top-level source code for G.723 dual-rate decoder +** +** Functions: Init_Decod() +** Dec_Cng() +** Decod() +** +** +*/ + +#include +#include +#include + +#include "typedef.h" +#include "basop.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "decod.h" +#include "util_lbc.h" +#include "lpc.h" +#include "lsp.h" +#include "exc_lbc.h" +#include "util_cng.h" + +/* +** +** Function: Init_Decod() +** +** Description: Initializes non-zero state variables +** for the decoder. +** +** Links to text: Section 3.11 +** +** Arguments: +** +** Flag UsePf Use postfilter +** +** Outputs: None +** +** Return value: Structure with decoding state +** +*/ +DECSTATDEF * +Init_Decod (Flag UsePf, enum Crate WrkRate) +{ + DECSTATDEF *DecStat; + int i; + + /* Initialize encoder data structure with zeros */ + DecStat = (DECSTATDEF *) malloc (sizeof (DECSTATDEF)); + memset (DecStat, 0, sizeof (DECSTATDEF)); + + /* Initialize the previously decoded LSP vector to the DC vector */ + for (i = 0; i < LpcOrder; i++) + DecStat->PrevLsp[i] = LspDcTable[i]; + + /* Initialize the gain scaling unit memory to a constant */ + DecStat->Gain = (Word16) 0x1000; + + DecStat->PastFtyp = 1; + DecStat->SidGain = 0; + for (i = 0; i < LpcOrder; i++) + DecStat->LspSid[i] = LspDcTable[i]; + DecStat->RandSeed = 12345; + + DecStat->UsePf = UsePf; + DecStat->WrkRate = WrkRate; + + return DecStat; +} + + +/* +** +** Function: Dec_Cng() +** +** Description: Receives Ftyp +** 0 : for untransmitted frames +** 2 : for SID frames +** Decodes SID frames +** Computes current frame excitation +** Computes current frame LSPs +** +** Links to text: +** +** Arguments: +** +** DECSTATDEF *DecStat Decoder state +** Word16 Ftyp Type of silence frame +** LINEDEF *Line Coded parameters +** Word16 *DataExc Current frame excitation +** Word16 *QntLpc Interpolated frame LPC coefficients +** +** Outputs: +** +** Word16 *DataExc +** Word16 *QntLpc +** +** Return value: None +** +*/ +void +Dec_Cng (DECSTATDEF * DecStat, Word16 Ftyp, LINEDEF * Line, Word16 * DataExc, + Word16 * QntLpc) +{ + + Word16 temp; + int i; + + if (Ftyp == 2) { + + /* + * SID Frame decoding + */ + DecStat->SidGain = Dec_SidGain (Line->Sfs[0].Mamp); + + /* Inverse quantization of the LSP */ + Lsp_Inq (DecStat->LspSid, DecStat->PrevLsp, Line->LspId, 0); + } + + else { + +/* + * non SID Frame + */ + if (DecStat->PastFtyp == 1) { + + /* + * Case of 1st SID frame erased : quantize-decode + * energy estimate stored in DecStat->SidGain + * scaling factor in DecStat->CurGain + */ + temp = Qua_SidGain (&DecStat->SidGain, &DecStat->CurGain, 0); + DecStat->SidGain = Dec_SidGain (temp); + } + } + + + if (DecStat->PastFtyp == 1) { + DecStat->CurGain = DecStat->SidGain; + } + else { + DecStat->CurGain = extract_h (L_add (L_mult (DecStat->CurGain, 0x7000), + L_mult (DecStat->SidGain, 0x1000))); + } + Calc_Exc_Rand (DecStat->WrkRate, DecStat->CurGain, DecStat->PrevExc, DataExc, + &DecStat->RandSeed, Line); + + /* Interpolate the Lsp vectors */ + Lsp_Int (QntLpc, DecStat->LspSid, DecStat->PrevLsp); + + /* Copy the LSP vector for the next frame */ + for (i = 0; i < LpcOrder; i++) + DecStat->PrevLsp[i] = DecStat->LspSid[i]; + + return; +} + + + +/* +** +** Function: Decod() +** +** Description: Implements G.723 dual-rate decoder for a frame +** of speech +** +** Links to text: Section 3 +** +** Arguments: +** +** DECSTATDEF *DecStat DecoderState +** Word16 *DataBuff Empty buffer +** Word16 Vinp[] Encoded frame (22/26 bytes) +** + +** Outputs: +** +** Word16 DataBuff[] Decoded frame (480 bytes) +** +** Return value: +** +** Flag Always True +** +*/ + +Flag +Decod (DECSTATDEF * DecStat, Word16 * DataBuff, char *Vinp, Word16 Crc) +{ + int i, j; + + Word32 Senr; + Word16 QntLpc[SubFrames * LpcOrder]; + Word16 AcbkCont[SubFrLen]; + + Word16 LspVect[LpcOrder]; + Word16 Temp[PitchMax + Frame]; + Word16 *Dpnt; + + LINEDEF Line; + PFDEF Pf[SubFrames]; + + Word16 Ftyp; + + /* + * Decode the packed bitstream for the frame. (Text: Section 4; + * pars of sections 2.17, 2.18) + */ + Line = Line_Unpk (&(DecStat->WrkRate), Vinp, &Ftyp, Crc); + + /* + * Update the frame erasure count (Text: Section 3.10) + */ + if (Line.Crc != (Word16) 0) { + if (DecStat->PastFtyp == 1) + Ftyp = 1; /* active */ + else + Ftyp = 0; /* untransmitted */ + } + + if (Ftyp != 1) { + /* Silence frame : do noise generation */ + Dec_Cng (DecStat, Ftyp, &Line, DataBuff, QntLpc); + } + + else { + + /* + * Update the frame erasure count (Text: Section 3.10) + */ + if (Line.Crc != (Word16) 0) + DecStat->Ecount = add (DecStat->Ecount, (Word16) 1); + else + DecStat->Ecount = (Word16) 0; + + if (DecStat->Ecount > (Word16) ErrMaxNum) + DecStat->Ecount = (Word16) ErrMaxNum; + + /* + * Decode the LSP vector for subframe 3. (Text: Section 3.2) + */ + Lsp_Inq (LspVect, DecStat->PrevLsp, Line.LspId, Line.Crc); + + /* + * Interpolate the LSP vectors for subframes 0--2. Convert the + * LSP vectors to LPC coefficients. (Text: Section 3.3) + */ + Lsp_Int (QntLpc, LspVect, DecStat->PrevLsp); + + /* Copy the LSP vector for the next frame */ + for (i = 0; i < LpcOrder; i++) + DecStat->PrevLsp[i] = LspVect[i]; + + /* + * In case of no erasure, update the interpolation gain memory. + * Otherwise compute the interpolation gain (Text: Section 3.10) + */ + if (DecStat->Ecount == (Word16) 0) { + DecStat->InterGain = add (Line.Sfs[SubFrames - 2].Mamp, + Line.Sfs[SubFrames - 1].Mamp); + DecStat->InterGain = shr (DecStat->InterGain, (Word16) 1); + DecStat->InterGain = FcbkGainTable[DecStat->InterGain]; + } + else + DecStat->InterGain = mult_r (DecStat->InterGain, (Word16) 0x6000); + + + /* + * Generate the excitation for the frame + */ + for (i = 0; i < PitchMax; i++) + Temp[i] = DecStat->PrevExc[i]; + + Dpnt = &Temp[PitchMax]; + + if (DecStat->Ecount == (Word16) 0) { + + for (i = 0; i < SubFrames; i++) { + + /* Generate the fixed codebook excitation for a + subframe. (Text: Section 3.5) */ + Fcbk_Unpk (DecStat->WrkRate, Dpnt, Line.Sfs[i], Line.Olp[i >> 1], + (Word16) i); + + /* Generate the adaptive codebook excitation for a + subframe. (Text: Section 3.4) */ + Decod_Acbk (DecStat->WrkRate, AcbkCont, &Temp[SubFrLen * i], + Line.Olp[i >> 1], Line.Sfs[i].AcLg, Line.Sfs[i].AcGn); + + /* Add the adaptive and fixed codebook contributions to + generate the total excitation. */ + for (j = 0; j < SubFrLen; j++) { + Dpnt[j] = shl (Dpnt[j], (Word16) 1); + Dpnt[j] = add (Dpnt[j], AcbkCont[j]); + } + + Dpnt += SubFrLen; + } + + /* Save the excitation */ + for (j = 0; j < Frame; j++) + DataBuff[j] = Temp[PitchMax + j]; + + /* Compute interpolation index. (Text: Section 3.10) */ + /* Use DecStat->SidGain and DecStat->CurGain to store */ + /* excitation energy estimation */ + DecStat->InterIndx = Comp_Info (Temp, Line.Olp[SubFrames / 2 - 1], + &DecStat->SidGain, &DecStat->CurGain); + + /* Compute pitch post filter coefficients. (Text: Section 3.6) */ + if (DecStat->UsePf) + for (i = 0; i < SubFrames; i++) + Pf[i] = + Comp_Lpf (DecStat->WrkRate, Temp, Line.Olp[i >> 1], (Word16) i); + + /* Reload the original excitation */ + for (j = 0; j < PitchMax; j++) + Temp[j] = DecStat->PrevExc[j]; + for (j = 0; j < Frame; j++) + Temp[PitchMax + j] = DataBuff[j]; + + /* Perform pitch post filtering for the frame. (Text: Section + 3.6) */ + if (DecStat->UsePf) + for (i = 0; i < SubFrames; i++) + Filt_Lpf (DataBuff, Temp, Pf[i], (Word16) i); + + /* Save Lsps --> LspSid */ + for (i = 0; i < LpcOrder; i++) + DecStat->LspSid[i] = DecStat->PrevLsp[i]; + } + + else { + + /* If a frame erasure has occurred, regenerate the + signal for the frame. (Text: Section 3.10) */ + Regen (DataBuff, Temp, DecStat->InterIndx, DecStat->InterGain, + DecStat->Ecount, &DecStat->Rseed); + } + + /* Update the previous excitation for the next frame */ + for (j = 0; j < PitchMax; j++) + DecStat->PrevExc[j] = Temp[Frame + j]; + + /* Resets random generator for CNG */ + DecStat->RandSeed = 12345; + } + + /* Save Ftyp information for next frame */ + DecStat->PastFtyp = Ftyp; + + /* + * Synthesize the speech for the frame + */ + Dpnt = DataBuff; + for (i = 0; i < SubFrames; i++) { + + /* Compute the synthesized speech signal for a subframe. + * (Text: Section 3.7) + */ + Synt (DecStat, Dpnt, &QntLpc[i * LpcOrder]); + + if (DecStat->UsePf) { + + /* Do the formant post filter. (Text: Section 3.8) */ + Senr = Spf (DecStat, Dpnt, &QntLpc[i * LpcOrder]); + + /* Do the gain scaling unit. (Text: Section 3.9) */ + DecStat->Gain = Scale (DecStat->Gain, Dpnt, Senr); + } + + Dpnt += SubFrLen; + } + return (Flag) True; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/decod.h asterisk-1.2.1/codecs/g723_1/decod.h --- asterisk-1.2.1.ori/codecs/g723_1/decod.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/decod.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,51 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "decod.h" +** +** Description: Function prototypes and external declarations +** for "decod.c" +** +*/ + +#ifndef _DECOD_H_ +#define _DECOD_H_ + +typedef struct +{ + Word16 Ecount; + Word16 InterGain; + Word16 InterIndx; + Word16 Rseed; + Word16 Park; + Word16 Gain; + /* Lsp previous vector */ + Word16 PrevLsp[LpcOrder]; + + /* All pitch operation buffers */ + Word16 PrevExc[PitchMax]; + + /* Used delay lines */ + Word16 SyntIirDl[LpcOrder]; + Word16 PostFirDl[LpcOrder]; + Word16 PostIirDl[LpcOrder]; + + /* DecCNG part */ + + Word16 CurGain; + Word16 PastFtyp; + Word16 LspSid[LpcOrder]; + Word16 SidGain; + Word16 RandSeed; + + /* Use postfilter */ + Flag UsePf; + enum Crate WrkRate; +} DECSTATDEF; + +DECSTATDEF *Init_Decod (Flag UsePf, enum Crate WrkRate); +Flag Decod (DECSTATDEF * DecStat, Word16 * DataBuff, char *Vinp, Word16 Crc); + +#endif /* _DECOD_H_ */ diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/exc_lbc.c asterisk-1.2.1/codecs/g723_1/exc_lbc.c --- asterisk-1.2.1.ori/codecs/g723_1/exc_lbc.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/exc_lbc.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,2837 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: exc_lbc.c +** +** Description: Functions that implement adaptive and fixed codebook +** operations. +** +** Functions: +** +** Computing Open loop Pitch lag: +** +** Estim_Pitch() +** +** Harmonic noise weighting: +** +** Comp_Pw() +** Filt_Pw() +** +** Fixed Cobebook computation: +** +** Find_Fcbk() +** Gen_Trn() +** Find_Best() +** Find_Pack() +** Find_Unpk() +** ACELP_LBC_code() +** Cor_h() +** Cor_h_X() +** reset_max_time() +** D4i64_LBC() +** G_code() +** search_T0() +** +** Adaptive Cobebook computation: +** +** Find_Acbk() +** Get_Rez() +** Decod_Acbk() +** +** Pitch postfilter: +** Comp_Lpf() +** Find_B() +** Find_F() +** Filt_Lpf() +** +** Residual interpolation: +** +** Comp_Info() +** Regen() +** +*/ + +#include +#include + +#include "typedef.h" +#include "basop.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "util_lbc.h" +#include "exc_lbc.h" +#include "tame.h" +#include "util_cng.h" + +/* +** +** Function: Estim_Pitch() +** +** Description: Open loop pitch estimation made twice per frame (one for +** the first two subframes and one for the last two). +** The method is based on the maximization of the +** crosscorrelation of the speech. +** +** Links to text: Section 2.9 +** +** Arguments: +** +** Word16 *Dpnt Perceptually weighted speech +** Word16 Start Starting index defining the subframes under study +** +** Outputs: +** +** Return value: +** +** Word16 Open loop pitch period +** +*/ +Word16 +Estim_Pitch (Word16 * Dpnt, Word16 Start) +{ + int i, j; + + Word32 Acc0, Acc1; + + Word16 Exp, Tmp; + Word16 Ccr, Enr; + + Word16 Indx = (Word16) PitchMin; + + Word16 Mxp = (Word16) 30; + Word16 Mcr = (Word16) 0x4000; + Word16 Mnr = (Word16) 0x7fff; + + Word16 Pr; + + /* Init the energy estimate */ + Pr = Start - (Word16) PitchMin + (Word16) 1; + Acc1 = (Word32) 0; + for (j = 0; j < 2 * SubFrLen; j++) + Acc1 = L_mac (Acc1, Dpnt[Pr + j], Dpnt[Pr + j]); + + /* Main Olp search loop */ + for (i = PitchMin; i <= PitchMax - 3; i++) { + + Pr = sub (Pr, (Word16) 1); + + /* Energy update */ + Acc1 = L_msu (Acc1, Dpnt[Pr + 2 * SubFrLen], Dpnt[Pr + 2 * SubFrLen]); + Acc1 = L_mac (Acc1, Dpnt[Pr], Dpnt[Pr]); + + /* Compute the cross */ + Acc0 = (Word32) 0; + for (j = 0; j < 2 * SubFrLen; j++) + Acc0 = L_mac (Acc0, Dpnt[Start + j], Dpnt[Pr + j]); + + if (Acc0 > (Word32) 0) { + + /* Compute Exp and mant of the cross */ + Exp = norm_l (Acc0); + Acc0 = L_shl (Acc0, Exp); + Exp = shl (Exp, (Word16) 1); + Ccr = L_round (Acc0); + Acc0 = L_mult (Ccr, Ccr); + Ccr = norm_l (Acc0); + Acc0 = L_shl (Acc0, Ccr); + Exp = add (Exp, Ccr); + Ccr = extract_h (Acc0); + + /* Do the same with energy */ + Acc0 = Acc1; + Enr = norm_l (Acc0); + Acc0 = L_shl (Acc0, Enr); + Exp = sub (Exp, Enr); + Enr = L_round (Acc0); + + if (Ccr >= Enr) { + Exp = sub (Exp, (Word16) 1); + Ccr = shr (Ccr, (Word16) 1); + } + + if (Exp <= Mxp) { + + if ((Exp + 1) < Mxp) { + Indx = (Word16) i; + Mxp = Exp; + Mcr = Ccr; + Mnr = Enr; + continue; + } + + if ((Exp + 1) == Mxp) + Tmp = shr (Mcr, (Word16) 1); + else + Tmp = Mcr; + + /* Compare with equal exponents */ + Acc0 = L_mult (Ccr, Mnr); + Acc0 = L_msu (Acc0, Enr, Tmp); + if (Acc0 > (Word32) 0) { + + if (((Word16) i - Indx) < (Word16) PitchMin) { + Indx = (Word16) i; + Mxp = Exp; + Mcr = Ccr; + Mnr = Enr; + } + + else { + Acc0 = L_mult (Ccr, Mnr); + Acc0 = L_negate (L_shr (Acc0, (Word16) 2)); + Acc0 = L_mac (Acc0, Ccr, Mnr); + Acc0 = L_msu (Acc0, Enr, Tmp); + if (Acc0 > (Word32) 0) { + Indx = (Word16) i; + Mxp = Exp; + Mcr = Ccr; + Mnr = Enr; + } + } + } + } + } + } + + return Indx; +} + +/* +** +** Function: Comp_Pw() +** +** Description: Computes harmonic noise filter coefficients. +** For each subframe, the optimal lag is searched around the +** open loop pitch lag based on only positive correlation +** maximization. +** +** Links to text: Section 2.11 +** +** Arguments: +** +** Word16 *Dpnt Formant perceptually weighted speech +** Word16 Start +** Word16 Olp Open loop pitch lag +** +** Outputs: None +** +** Return value: +** +** PWDEF Word16 Indx lag of the harmonic noise shaping filter +** Word16 Gain gain of the harmonic noise shaping filter +** +*/ +PWDEF +Comp_Pw (Word16 * Dpnt, Word16 Start, Word16 Olp) +{ + + int i, j; + + Word32 Lcr[15]; + Word16 Scr[15]; + PWDEF Pw; + + Word32 Acc0, Acc1; + Word16 Exp; + + Word16 Ccr, Enr; + Word16 Mcr, Mnr; + + /* Compute and save target energy */ + Lcr[0] = (Word32) 0; + for (i = 0; i < SubFrLen; i++) + Lcr[0] = L_mac (Lcr[0], Dpnt[Start + i], Dpnt[Start + i]); + + /* Compute all Crosses and energys */ + for (i = 0; i <= 2 * PwRange; i++) { + + Acc1 = Acc0 = (Word32) 0; + for (j = 0; j < SubFrLen; j++) { + Acc0 = L_mac (Acc0, Dpnt[Start + j], + Dpnt[Start - (Olp - PwRange + i) + j]); + Acc1 = L_mac (Acc1, Dpnt[Start - (Olp - PwRange + i) + j], + Dpnt[Start - (Olp - PwRange + i) + j]); + } + + /* Save both */ + Lcr[2 * i + 1] = Acc1; + Lcr[2 * i + 2] = Acc0; + } + + /* Normalize to maximum */ + Acc1 = (Word32) 0; + for (i = 0; i < 15; i++) { + Acc0 = Lcr[i]; + Acc0 = L_abs (Acc0); + if (Acc0 > Acc1) + Acc1 = Acc0; + } + + Exp = norm_l (Acc1); + for (i = 0; i < 15; i++) { + Acc0 = L_shl (Lcr[i], Exp); + Scr[i] = L_round (Acc0); + + } + + /* Find the best pair */ + Pw.Indx = (Word16) - 1; + Pw.Gain = (Word16) 0; + + Mcr = (Word16) 1; + Mnr = (Word16) 0x7fff; + + for (i = 0; i <= 2 * PwRange; i++) { + + Enr = Scr[2 * i + 1]; + Ccr = Scr[2 * i + 2]; + + if (Ccr <= (Word16) 0) + continue; + + Exp = mult_r (Ccr, Ccr); + + /* Compute the cross */ + Acc0 = L_mult (Exp, Mnr); + Acc0 = L_msu (Acc0, Enr, Mcr); + + if (Acc0 > (Word32) 0) { + Mcr = Exp; + Mnr = Enr; + Pw.Indx = (Word16) i; + } + } + + if (Pw.Indx == -1) { + Pw.Indx = Olp; + return Pw; + } + + /* Check the db limit */ + Acc0 = L_mult (Scr[0], Mnr); + Acc1 = Acc0; + Acc0 = L_shr (Acc0, (Word16) 2); + Acc1 = L_shr (Acc1, (Word16) 3); + Acc0 = L_add (Acc0, Acc1); + Acc1 = L_mult (Scr[2 * Pw.Indx + 2], Scr[2 * Pw.Indx + 2]); + Acc0 = L_sub (Acc0, Acc1); + + if (Acc0 < (Word32) 0) { + + Exp = Scr[2 * Pw.Indx + 2]; + + if (Exp >= Mnr) + Pw.Gain = PwConst; + else { + Pw.Gain = div_s (Exp, Mnr); + Pw.Gain = mult_r (Pw.Gain, PwConst); + } + } + + Pw.Indx = Olp - PwRange + Pw.Indx; + + return Pw; + +} + +/* +** +** Function: Filt_Pw() +** +** Description: Applies harmonic noise shaping filter. +** Lth order FIR filter on each subframe (L: lag of the filter). +** +** Links to text: Section 2.11 +** +** Arguments: +** +** Word16 *DataBuff Target vector +** Word16 *Dpnt Formant perceptually weighted speech +** Word16 Start +** PWDEF Pw Parameters of the harmonic noise shaping filter +** +** Outputs: +** +** Word16 *DataBuff Target vector +** +** Return value: None +** +*/ +void +Filt_Pw (Word16 * DataBuff, Word16 * Dpnt, Word16 Start, PWDEF Pw) +{ + int i; + + Word32 Acc0; + + /* Perform the harmonic weighting */ + for (i = 0; i < SubFrLen; i++) { + Acc0 = L_deposit_h (Dpnt[PitchMax + Start + i]); + Acc0 = L_msu (Acc0, Pw.Gain, Dpnt[PitchMax + Start - Pw.Indx + i]); + DataBuff[Start + (Word16) i] = L_round (Acc0); + } + + return; +} + +/* +** +** Function: Find_Fcbk() +** +** Description: Fixed codebook excitation computation. +** +** +** Links to text: Sections 2.15 & 2.16 +** +** Arguments: +** +** Word16 *Dpnt Target vector +** Word16 *ImpResp Impulse response of the synthesis filter +** LineDef *Line Excitation parameters for one subframe +** Word16 Sfc Subframe index +** +** Outputs: +** +** Word16 *Dpnt Excitation vector +** LINEDEF *Line Fixed codebook parameters for one subframe +** +** Return value: None +** +*/ +void +Find_Fcbk (enum Crate WrkRate, Word16 * Dpnt, Word16 * ImpResp, + LINEDEF * Line, Word16 Sfc) +{ + int i; + Word16 T0_acelp, gain_T0; + Word16 Srate; + + + BESTDEF Best; + + switch (WrkRate) { + + case Rate63:{ + + Srate = Nb_puls[(int) Sfc]; + Best.MaxErr = (Word32) 0xc0000000L; + Find_Best (&Best, Dpnt, ImpResp, Srate, (Word16) SubFrLen); + if ((*Line).Olp[Sfc >> 1] < (Word16) (SubFrLen - 2)) { + Find_Best (&Best, Dpnt, ImpResp, Srate, (*Line).Olp[Sfc >> 1]); + } + + /* Reconstruct the excitation */ + for (i = 0; i < SubFrLen; i++) + Dpnt[i] = (Word16) 0; + for (i = 0; i < Srate; i++) + Dpnt[Best.Ploc[i]] = Best.Pamp[i]; + + /* Code the excitation */ + Fcbk_Pack (Dpnt, &((*Line).Sfs[Sfc]), &Best, Srate); + + if (Best.UseTrn == (Word16) 1) + Gen_Trn (Dpnt, Dpnt, (*Line).Olp[Sfc >> 1]); + + break; + } + + case Rate53:{ + + T0_acelp = search_T0 ((Word16) + ((*Line).Olp[Sfc >> 1] - 1 + + (*Line).Sfs[Sfc].AcLg), (*Line).Sfs[Sfc].AcGn, + &gain_T0); + + (*Line).Sfs[Sfc].Ppos = + ACELP_LBC_code (Dpnt, ImpResp, T0_acelp, Dpnt, &(*Line).Sfs[Sfc].Mamp, + &(*Line).Sfs[Sfc].Grid, &(*Line).Sfs[Sfc].Pamp, + gain_T0); + + (*Line).Sfs[Sfc].Tran = 0; + + break; + } + } + + return; +} + +/* +** +** Function: Gen_Trn() +** +** Description: Generation of a train of Dirac functions with the period +** Olp. +** +** Links to text: Section 2.15 +** +** Arguments: +** +** Word16 *Dst Fixed codebook excitation vector with train of Dirac +** Word16 *Src Fixed codebook excitation vector without train of Dirac +** Word16 Olp Closed-loop pitch lag of subframe 0 (for subframes 0 & 1) +** Closed-loop pitch lag of subframe 2 (for subframes 2 & 3) +** +** Outputs: +** +** Word16 *Dst excitation vector +** +** Return value: None +** +*/ +void +Gen_Trn (Word16 * Dst, Word16 * Src, Word16 Olp) +{ + int i; + + Word16 Tmp0, Tmp1; + Word16 Tmp[SubFrLen]; + + Tmp0 = Olp; + + for (i = 0; i < SubFrLen; i++) { + Tmp[i] = Src[i]; + Dst[i] = Src[i]; + } + + while (Tmp0 < SubFrLen) { + for (i = (int) Tmp0; i < SubFrLen; i++) { + Tmp1 = add (Dst[i], Tmp[i - (int) Tmp0]); + Dst[i] = Tmp1; + } + Tmp0 = add (Tmp0, Olp); + } + + return; +} + +/* +** +** Function: Find_Best() +** +** Description: Fixed codebook search for the high rate encoder. +** It performs the quantization of the residual signal. +** The excitation made of Np positive or negative pulses +** multiplied by a gain and whose positions on the grid are +** either all odd or all even, should approximate as best as +** possible the residual signal (perceptual criterion). +** +** Links to text: Section 2.15 +** +** Arguments: +** +** BESTDEF *Best Parameters of the best excitation model +** Word16 *Tv Target vector +** Word16 *ImpResp Impulse response of the combined filter +** Word16 Np Number of pulses (6 for even subframes; 5 for odd subframes) +** Word16 Olp Closed-loop pitch lag of subframe 0 (for subframes 0 & 1) +** Closed-loop pitch lag of subframe 2 (for subframes 2 & 3) +** +** Outputs: +** +** BESTDEF *Best +** +** Return value: None +** +*/ +void +Find_Best (BESTDEF * Best, Word16 * Tv, Word16 * ImpResp, Word16 Np, + Word16 Olp) +{ + + int i, j, k, l; + BESTDEF Temp; + + Word16 Exp; + Word16 MaxAmpId; + Word16 MaxAmp; + Word32 Acc0, Acc1, Acc2; + + Word16 Imr[SubFrLen]; + Word16 OccPos[SubFrLen]; + Word16 ImrCorr[SubFrLen]; + Word32 ErrBlk[SubFrLen]; + Word32 WrkBlk[SubFrLen]; + + + /* Update Impulse response */ + if (Olp < (Word16) (SubFrLen - 2)) { + Temp.UseTrn = (Word16) 1; + Gen_Trn (Imr, ImpResp, Olp); + } + else { + Temp.UseTrn = (Word16) 0; + for (i = 0; i < SubFrLen; i++) + Imr[i] = ImpResp[i]; + } + + /* Scale Imr to avoid overflow */ + for (i = 0; i < SubFrLen; i++) + OccPos[i] = shr (Imr[i], (Word16) 1); + + /* Compute Imr AutoCorr function */ + Acc0 = (Word32) 0; + for (i = 0; i < SubFrLen; i++) + Acc0 = L_mac (Acc0, OccPos[i], OccPos[i]); + + Exp = norm_l (Acc0); + Acc0 = L_shl (Acc0, Exp); + ImrCorr[0] = L_round (Acc0); + + /* Compute all the other */ + for (i = 1; i < SubFrLen; i++) { + Acc0 = (Word32) 0; + for (j = i; j < SubFrLen; j++) + Acc0 = L_mac (Acc0, OccPos[j], OccPos[j - i]); + Acc0 = L_shl (Acc0, Exp); + ImrCorr[i] = L_round (Acc0); + } + + /* Cross correlation with the signal */ + Exp = sub (Exp, 4); + for (i = 0; i < SubFrLen; i++) { + Acc0 = (Word32) 0; + for (j = i; j < SubFrLen; j++) + Acc0 = L_mac (Acc0, Tv[j], Imr[j - i]); + ErrBlk[i] = L_shl (Acc0, Exp); + } + + /* Search for the best sequence */ + for (k = 0; k < Sgrid; k++) { + + Temp.GridId = (Word16) k; + + /* Find maximum amplitude */ + Acc1 = (Word32) 0; + for (i = k; i < SubFrLen; i += Sgrid) { + Acc0 = L_abs (ErrBlk[i]); + if (Acc0 >= Acc1) { + Acc1 = Acc0; + Temp.Ploc[0] = (Word16) i; + } + } + + /* Quantize the maximum amplitude */ + Acc2 = Acc1; + Acc1 = (Word32) 0x40000000L; + MaxAmpId = (Word16) (NumOfGainLev - MlqSteps); + + for (i = MaxAmpId; i >= MlqSteps; i--) { + Acc0 = L_mult (FcbkGainTable[i], ImrCorr[0]); + Acc0 = L_sub (Acc0, Acc2); + Acc0 = L_abs (Acc0); + if (Acc0 < Acc1) { + Acc1 = Acc0; + MaxAmpId = (Word16) i; + } + } + MaxAmpId--; + + for (i = 1; i <= 2 * MlqSteps; i++) { + + for (j = k; j < SubFrLen; j += Sgrid) { + WrkBlk[j] = ErrBlk[j]; + OccPos[j] = (Word16) 0; + } + Temp.MampId = MaxAmpId - (Word16) MlqSteps + (Word16) i; + + MaxAmp = FcbkGainTable[Temp.MampId]; + + if (WrkBlk[Temp.Ploc[0]] >= (Word32) 0) + Temp.Pamp[0] = MaxAmp; + else + Temp.Pamp[0] = negate (MaxAmp); + + OccPos[Temp.Ploc[0]] = (Word16) 1; + + for (j = 1; j < Np; j++) { + + Acc1 = (Word32) 0xc0000000L; + + for (l = k; l < SubFrLen; l += Sgrid) { + + if (OccPos[l] != (Word16) 0) + continue; + + Acc0 = WrkBlk[l]; + Acc0 = L_msu (Acc0, Temp.Pamp[j - 1], + ImrCorr[abs_s ((Word16) (l - Temp.Ploc[j - 1]))]); + WrkBlk[l] = Acc0; + Acc0 = L_abs (Acc0); + if (Acc0 > Acc1) { + Acc1 = Acc0; + Temp.Ploc[j] = (Word16) l; + } + } + + if (WrkBlk[Temp.Ploc[j]] >= (Word32) 0) + Temp.Pamp[j] = MaxAmp; + else + Temp.Pamp[j] = negate (MaxAmp); + + OccPos[Temp.Ploc[j]] = (Word16) 1; + } + + /* Compute error vector */ + for (j = 0; j < SubFrLen; j++) + OccPos[j] = (Word16) 0; + + for (j = 0; j < Np; j++) + OccPos[Temp.Ploc[j]] = Temp.Pamp[j]; + + for (l = SubFrLen - 1; l >= 0; l--) { + Acc0 = (Word32) 0; + for (j = 0; j <= l; j++) + Acc0 = L_mac (Acc0, OccPos[j], Imr[l - j]); + Acc0 = L_shl (Acc0, (Word16) 2); + OccPos[l] = extract_h (Acc0); + } + + /* Evaluate error */ + Acc1 = (Word32) 0; + for (j = 0; j < SubFrLen; j++) { + Acc1 = L_mac (Acc1, Tv[j], OccPos[j]); + Acc0 = L_mult (OccPos[j], OccPos[j]); + Acc1 = L_sub (Acc1, L_shr (Acc0, (Word16) 1)); + } + + if (Acc1 > (*Best).MaxErr) { + (*Best).MaxErr = Acc1; + (*Best).GridId = Temp.GridId; + (*Best).MampId = Temp.MampId; + (*Best).UseTrn = Temp.UseTrn; + for (j = 0; j < Np; j++) { + (*Best).Pamp[j] = Temp.Pamp[j]; + (*Best).Ploc[j] = Temp.Ploc[j]; + } + } + } + } + return; +} + +/* +** +** Function: Fcbk_Pack() +** +** Description: Encoding of the pulse positions and gains for the high +** rate case. +** Combinatorial encoding is used to transmit the optimal +** combination of pulse locations. +** +** Links to text: Section 2.15 +** +** Arguments: +** +** Word16 *Dpnt Excitation vector +** SFSDEF *Sfs Encoded parameters of the excitation model +** BESTDEF *Best Parameters of the best excitation model +** Word16 Np Number of pulses (6 for even subframes; 5 for odd subframes) +** +** Outputs: +** +** SFSDEF *Sfs Encoded parameters of the excitation model +** +** Return value: None +** +*/ +void +Fcbk_Pack (Word16 * Dpnt, SFSDEF * Sfs, BESTDEF * Best, Word16 Np) +{ + int i, j; + + + /* Code the amplitudes and positions */ + j = MaxPulseNum - (int) Np; + + (*Sfs).Pamp = (Word16) 0; + (*Sfs).Ppos = (Word32) 0; + + for (i = 0; i < SubFrLen / Sgrid; i++) { + + if (Dpnt[(int) (*Best).GridId + Sgrid * i] == (Word16) 0) + (*Sfs).Ppos = L_add ((*Sfs).Ppos, CombinatorialTable[j][i]); + else { + (*Sfs).Pamp = shl ((*Sfs).Pamp, (Word16) 1); + if (Dpnt[(int) (*Best).GridId + Sgrid * i] < (Word16) 0) + (*Sfs).Pamp = add ((*Sfs).Pamp, (Word16) 1); + + j++; + /* Check for end */ + if (j == MaxPulseNum) + break; + } + } + + (*Sfs).Mamp = (*Best).MampId; + (*Sfs).Grid = (*Best).GridId; + (*Sfs).Tran = (*Best).UseTrn; + + return; +} + +/* +** +** Function: Fcbk_Unpk() +** +** Description: Decoding of the fixed codebook excitation for both rates. +** Gains, pulse positions, grid position (odd or even), signs +** are decoded and used to reconstruct the excitation. +** +** Links to text: Section 2.17 & 3.5 +** +** Arguments: +** +** Word16 *Tv Decoded excitation vector +** SFSDEF Sfs Encoded parameters of the excitation (for one subframe) +** Word16 Olp Closed loop adaptive pitch lag +** Word16 Sfc Subframe index +** +** Outputs: +** +** Word16 *Tv Decoded excitation vector +** +** Return value: None +** +*/ +void +Fcbk_Unpk (enum Crate WrkRate, Word16 * Tv, SFSDEF Sfs, Word16 Olp, + Word16 Sfc) +{ + int i, j; + + Word32 Acc0; + Word16 Np; + Word16 Tv_tmp[SubFrLen + 4]; + Word16 acelp_gain, acelp_sign, acelp_shift, acelp_pos; + Word16 offset, ipos, T0_acelp, gain_T0; + + + + switch (WrkRate) { + case Rate63:{ + + Np = Nb_puls[(int) Sfc]; + + for (i = 0; i < SubFrLen; i++) + Tv[i] = (Word16) 0; + + if (Sfs.Ppos >= MaxPosTable[Sfc]) + return; + + /* Decode the amplitudes and positions */ + j = MaxPulseNum - (int) Np; + + Acc0 = Sfs.Ppos; + + for (i = 0; i < SubFrLen / Sgrid; i++) { + + Acc0 = L_sub (Acc0, CombinatorialTable[j][i]); + + if (Acc0 < (Word32) 0) { + Acc0 = L_add (Acc0, CombinatorialTable[j][i]); + j++; + if ((Sfs.Pamp & (1 << (MaxPulseNum - j))) != (Word16) 0) + Tv[(int) Sfs.Grid + Sgrid * i] = -FcbkGainTable[Sfs.Mamp]; + else + Tv[(int) Sfs.Grid + Sgrid * i] = FcbkGainTable[Sfs.Mamp]; + + if (j == MaxPulseNum) + break; + } + } + + if (Sfs.Tran == (Word16) 1) + Gen_Trn (Tv, Tv, Olp); + break; + } + + case Rate53:{ + for (i = 0; i < SubFrLen + 4; i++) + Tv_tmp[i] = (Word16) 0; + + /* decoding gain */ + acelp_gain = FcbkGainTable[Sfs.Mamp]; + /* decoding grid */ + acelp_shift = Sfs.Grid; + /* decoding Sign */ + acelp_sign = Sfs.Pamp; + /* decoding Pos */ + acelp_pos = (short) Sfs.Ppos; + + offset = 0; + for (i = 0; i < 4; i++) { + ipos = (acelp_pos & (Word16) 0x0007); + ipos = shl (ipos, 3) + acelp_shift + offset; + if ((acelp_sign & 1) == 1) { + Tv_tmp[ipos] = acelp_gain; + } + else { + Tv_tmp[ipos] = -acelp_gain; + } + offset = add (offset, 2); + acelp_pos = shr (acelp_pos, 3); + acelp_sign = shr (acelp_sign, 1); + } + for (i = 0; i < SubFrLen; i++) + Tv[i] = Tv_tmp[i]; + T0_acelp = search_T0 ((Word16) (Olp - 1 + Sfs.AcLg), Sfs.AcGn, + &gain_T0); + if (T0_acelp < SubFrLen - 2) { + /* code[i] += 0.8 * code[i-Olp] */ + for (i = T0_acelp; i < SubFrLen; i++) + Tv[i] = add (Tv[i], mult (Tv[i - T0_acelp], gain_T0)); + } + + break; + } + } + return; +} + +/* +** +** Function: Find_Acbk() +** +** Description: Computation of adaptive codebook contribution in +** closed-loop around the open-loop pitch lag (subframes 0 & 2) +** around the previous subframe closed-loop pitch lag +** (subframes 1 & 3). For subframes 0 & 2, the pitch lag is +** encoded whereas for subframes 1 & 3, only the difference +** with the previous value is encoded (-1, 0, +1 or +2). +** The pitch predictor gains are quantized using one of the two +** codebooks (85 entries or 170 entries) depending on the +** rate and on the pitch lag value. +** Finally, the contribution of the pitch predictor is decoded +** and subtracted to obtain the residual signal. +** +** Links to text: Section 2.14 +** +** Arguments: +** +** Word16 *Tv Target vector +** Word16 *ImpResp Impulse response of the combined filter +** Word16 *PrevExc Previous excitation vector +** LINEDEF *Line Contains pitch related parameters (open/closed loop lag, gain) +** Word16 Sfc Subframe index +** +** Outputs: +** +** Word16 *Tv Residual vector +** LINEDEF *Line Contains pitch related parameters (closed loop lag, gain) +** +** Return value: None +** +*/ +void +Find_Acbk (CODSTATDEF * CodStat, Word16 * Tv, Word16 * ImpResp, + Word16 * PrevExc, LINEDEF * Line, Word16 Sfc) +{ + int i, j, k, l; + + Word32 Acc0, Acc1; + + Word16 RezBuf[SubFrLen + ClPitchOrd - 1]; + Word16 FltBuf[ClPitchOrd][SubFrLen]; + Word32 CorBuf[4 * (2 * ClPitchOrd + ClPitchOrd * (ClPitchOrd - 1) / 2)]; + Word32 *lPnt; + + Word16 CorVct[4 * (2 * ClPitchOrd + ClPitchOrd * (ClPitchOrd - 1) / 2)]; + Word16 *sPnt; + + Word16 Olp; + Word16 Lid; + Word16 Gid; + Word16 Hb; + Word16 Exp; + Word16 Bound[2]; + + Word16 Lag1, Lag2; + Word16 off_filt; + + /* Init constants */ + Olp = (*Line).Olp[shr (Sfc, (Word16) 1)]; + Lid = (Word16) Pstep; + Gid = (Word16) 0; + Hb = (Word16) 3 + (Sfc & (Word16) 1); + + /* For even frames only */ + if ((Sfc & (Word16) 1) == (Word16) 0) { + if (Olp == (Word16) PitchMin) + Olp = add (Olp, (Word16) 1); + if (Olp > (Word16) (PitchMax - 5)) + Olp = (Word16) (PitchMax - 5); + } + + lPnt = CorBuf; + for (k = 0; k < (int) Hb; k++) { + + /* Get residual from the excitation buffer */ + Get_Rez (RezBuf, PrevExc, (Word16) (Olp - (Word16) Pstep + k)); + + /* Filter the last one using the impulse response */ + for (i = 0; i < SubFrLen; i++) { + Acc0 = (Word32) 0; + for (j = 0; j <= i; j++) + Acc0 = L_mac (Acc0, RezBuf[ClPitchOrd - 1 + j], ImpResp[i - j]); + FltBuf[ClPitchOrd - 1][i] = L_round (Acc0); + } + + /* Update all the others */ + for (i = ClPitchOrd - 2; i >= 0; i--) { + FltBuf[i][0] = mult_r (RezBuf[i], (Word16) 0x2000); + for (j = 1; j < SubFrLen; j++) { + Acc0 = L_deposit_h (FltBuf[i + 1][j - 1]); + Acc0 = L_mac (Acc0, RezBuf[i], ImpResp[j]); + FltBuf[i][j] = L_round (Acc0); + } + } + + /* Compute the cross with the signal */ + for (i = 0; i < ClPitchOrd; i++) { + Acc1 = (Word32) 0; + for (j = 0; j < SubFrLen; j++) { + Acc0 = L_mult (Tv[j], FltBuf[i][j]); + Acc1 = L_add (Acc1, L_shr (Acc0, (Word16) 1)); + } + *lPnt++ = L_shl (Acc1, (Word16) 1); + } + + /* Compute the energies */ + for (i = 0; i < ClPitchOrd; i++) { + Acc1 = (Word32) 0; + for (j = 0; j < SubFrLen; j++) + Acc1 = L_mac (Acc1, FltBuf[i][j], FltBuf[i][j]); + *lPnt++ = Acc1; + } + + /* Compute the between crosses */ + for (i = 1; i < ClPitchOrd; i++) { + for (j = 0; j < i; j++) { + Acc1 = (Word32) 0; + for (l = 0; l < SubFrLen; l++) { + Acc0 = L_mult (FltBuf[i][l], FltBuf[j][l]); + Acc1 = L_add (Acc1, L_shr (Acc0, (Word16) 1)); + } + *lPnt++ = L_shl (Acc1, (Word16) 2); + } + } + } + + + /* Find Max and normalize */ + Acc1 = (Word32) 0; + for (i = 0; i < Hb * 20; i++) { + Acc0 = L_abs (CorBuf[i]); + if (Acc0 > Acc1) + Acc1 = Acc0; + } + + Exp = norm_l (Acc1); + /* Convert to shorts */ + for (i = 0; i < Hb * 20; i++) { + Acc0 = L_shl (CorBuf[i], Exp); + CorVct[i] = L_round (Acc0); + } + + /* Test potential error */ + Lag1 = Olp - (Word16) Pstep; + Lag2 = Olp - (Word16) Pstep + Hb - (Word16) 1; + off_filt = Test_Err (CodStat, Lag1, Lag2); + Bound[0] = NbFilt085_min + shl (off_filt, 2); + if (Bound[0] > NbFilt085) + Bound[0] = NbFilt085; + Bound[1] = NbFilt170_min + shl (off_filt, 3); + if (Bound[1] > NbFilt170) + Bound[1] = NbFilt170; + + /* Init the search loop */ + Acc1 = (Word32) 0; + + for (k = 0; k < (int) Hb; k++) { + + /* Select Quantization tables */ + l = 0; + if (CodStat->WrkRate == Rate63) { + if ((Sfc & (Word16) 1) == (Word16) 0) { + if ((int) Olp - Pstep + k >= SubFrLen - 2) + l++; + } + else { + if ((int) Olp >= SubFrLen - 2) + l++; + } + } + else { + l = 1; + } + + + sPnt = AcbkGainTablePtr[l]; + + for (i = 0; i < (int) Bound[l]; i++) { + + Acc0 = (Word32) 0; + for (j = 0; j < 20; j++) + Acc0 = L_add (Acc0, L_shr (L_mult (CorVct[k * 20 + j], *sPnt++), + (Word16) 1)); + + if (Acc0 > Acc1) { + Acc1 = Acc0; + Gid = (Word16) i; + Lid = (Word16) k; + } + } + } + + /* Modify Olp for even sub frames */ + if ((Sfc & (Word16) 1) == (Word16) 0) { + Olp = Olp - (Word16) Pstep + Lid; + Lid = (Word16) Pstep; + } + + /* Save Gains and Olp */ + (*Line).Sfs[Sfc].AcLg = Lid; + (*Line).Sfs[Sfc].AcGn = Gid; + (*Line).Olp[shr (Sfc, (Word16) 1)] = Olp; + + /* Decode the Acbk contribution and subtract it */ + Decod_Acbk (CodStat->WrkRate, RezBuf, PrevExc, Olp, Lid, Gid); + + for (i = 0; i < SubFrLen; i++) { + Acc0 = L_deposit_h (Tv[i]); + Acc0 = L_shr (Acc0, (Word16) 1); + + for (j = 0; j <= i; j++) + Acc0 = L_msu (Acc0, RezBuf[j], ImpResp[i - j]); + Acc0 = L_shl (Acc0, (Word16) 1); + Tv[i] = L_round (Acc0); + } + + return; +} + +/* +** +** Function: Get_Rez() +** +** Description: Gets delayed contribution from the previous excitation +** vector. +** +** Links to text: Sections 2.14, 2.18 & 3.4 +** +** Arguments: +** +** Word16 *Tv delayed excitation +** Word16 *PrevExc Previous excitation vector +** Word16 Lag Closed loop pitch lag +** +** Outputs: +** +** Word16 *Tv delayed excitation +** +** Return value: None +** +*/ +void +Get_Rez (Word16 * Tv, Word16 * PrevExc, Word16 Lag) +{ + int i; + + for (i = 0; i < ClPitchOrd / 2; i++) + Tv[i] = PrevExc[PitchMax - (int) Lag - ClPitchOrd / 2 + i]; + + for (i = 0; i < SubFrLen + ClPitchOrd / 2; i++) + Tv[ClPitchOrd / 2 + i] = PrevExc[PitchMax - (int) Lag + i % (int) Lag]; + + return; +} + +/* +** +** Function: Decod_Acbk() +** +** Description: Computes the adaptive codebook contribution from the previous +** excitation vector. +** With the gain index, the closed loop pitch lag, the jitter +** which when added to this pitch lag gives the actual closed +** loop value, and after having selected the proper codebook, +** the pitch contribution is reconstructed using the previous +** excitation buffer. +** +** Links to text: Sections 2.14, 2.18 & 3.4 +** +** Arguments: +** +** Word16 *Tv Reconstructed excitation vector +** Word16 *PrevExc Previous excitation vector +** Word16 Olp closed-loop pitch period +** Word16 Lid Jitter around pitch period +** Word16 Gid Gain vector index in 5- dimensional +** adaptive gain vector codebook +** +** Outputs: +** +** Word16 *Tv Reconstructed excitation vector +** +** Return value: None +** +*/ +void +Decod_Acbk (enum Crate WrkRate, Word16 * Tv, Word16 * PrevExc, Word16 Olp, + Word16 Lid, Word16 Gid) +{ + int i, j; + + Word32 Acc0; + Word16 RezBuf[SubFrLen + ClPitchOrd - 1]; + Word16 *sPnt; + + Get_Rez (RezBuf, PrevExc, (Word16) (Olp - (Word16) Pstep + Lid)); + + /* Select Quantization tables */ + i = 0; + if (WrkRate == Rate63) { + if (Olp >= (Word16) (SubFrLen - 2)) + i++; + } + else { + i = 1; + } + sPnt = AcbkGainTablePtr[i]; + + sPnt += (int) Gid *20; + + for (i = 0; i < SubFrLen; i++) { + Acc0 = (Word32) 0; + for (j = 0; j < ClPitchOrd; j++) + Acc0 = L_mac (Acc0, RezBuf[i + j], sPnt[j]); + Acc0 = L_shl (Acc0, (Word16) 1); + Tv[i] = L_round (Acc0); + } + + return; +} + +/* +** +** Function: Comp_Info() +** +** Description: Voiced/unvoiced classifier. +** It is based on a cross correlation maximization over the +** last 120 samples of the frame and with an index varying +** around the decoded pitch lag (from L-3 to L+3). Then the +** prediction gain is tested to declare the frame voiced or +** unvoiced. +** +** Links to text: Section 3.10.2 +** +** Arguments: +** +** Word16 *Buff decoded excitation +** Word16 Olp Decoded pitch lag +** +** Outputs: None +** +** Return value: +** +** Word16 Estimated pitch value +*/ +Word16 +Comp_Info (Word16 * Buff, Word16 Olp, Word16 * Gain, Word16 * ShGain) +{ + int i, j; + + Word32 Acc0, Acc1; + + Word16 Tenr; + Word16 Ccr, Enr; + Word16 Indx; + + /* Normalize the excitation */ + *ShGain = Vec_Norm (Buff, (Word16) (PitchMax + Frame)); + + if (Olp > (Word16) (PitchMax - 3)) + Olp = (Word16) (PitchMax - 3); + + Indx = Olp; + + Acc1 = (Word32) 0; + + for (i = (int) Olp - 3; i <= (int) Olp + 3; i++) { + + Acc0 = (Word32) 0; + for (j = 0; j < 2 * SubFrLen; j++) + Acc0 = L_mac (Acc0, Buff[PitchMax + Frame - 2 * SubFrLen + j], + Buff[PitchMax + Frame - 2 * SubFrLen - i + j]); + + if (Acc0 > Acc1) { + Acc1 = Acc0; + Indx = (Word16) i; + } + } + + /* Compute target energy */ + Acc0 = (Word32) 0; + for (j = 0; j < 2 * SubFrLen; j++) + Acc0 = L_mac (Acc0, Buff[PitchMax + Frame - 2 * SubFrLen + j], + Buff[PitchMax + Frame - 2 * SubFrLen + j]); + Tenr = L_round (Acc0); + *Gain = Tenr; + + /* Compute best energy */ + Acc0 = (Word32) 0; + for (j = 0; j < 2 * SubFrLen; j++) + Acc0 = + L_mac (Acc0, Buff[PitchMax + Frame - 2 * SubFrLen - (int) Indx + j], + Buff[PitchMax + Frame - 2 * SubFrLen - (int) Indx + j]); + + Ccr = L_round (Acc1); + + if (Ccr <= (Word16) 0) + return (Word16) 0; + + Enr = L_round (Acc0); + + Acc0 = L_mult (Enr, Tenr); + Acc0 = L_shr (Acc0, (Word16) 3); + + Acc0 = L_msu (Acc0, Ccr, Ccr); + + if (Acc0 < (Word32) 0) + return Indx; + else + return (Word16) 0; +} + +/* +** +** Function: Regen() +** +** Description: Performs residual interpolation depending of the frame +** classification. +** If the frame is previously declared unvoiced, the excitation +** is regenerated using a random number generator. Otherwise +** a periodic excitation is generated with the period +** previously found. +** +** Links to text: Section 3.10.2 +** +** Arguments: +** +** Word16 *DataBuff current subframe decoded excitation +** Word16 *Buff past decoded excitation +** Word16 Lag Decoded pitch lag from previous frame +** Word16 Gain Interpolated gain from previous frames +** Word16 Ecount Number of erased frames +** Word16 *Sd Random number used in unvoiced cases +** +** Outputs: +** +** Word16 *DataBuff current subframe decoded excitation +** Word16 *Buff updated past excitation +** +** Return value: None +** +*/ +void +Regen (Word16 * DataBuff, Word16 * Buff, Word16 Lag, Word16 Gain, + Word16 Ecount, Word16 * Sd) +{ + int i; + + /* Test for clearing */ + if (Ecount >= (Word16) ErrMaxNum) { + for (i = 0; i < Frame; i++) + DataBuff[i] = (Word16) 0; + for (i = 0; i < Frame + PitchMax; i++) + Buff[i] = (Word16) 0; + } + else { + /* Interpolate accordingly to the voicing estimation */ + if (Lag != (Word16) 0) { + /* Voiced case */ + for (i = 0; i < Frame; i++) + Buff[PitchMax + i] = Buff[PitchMax - (int) Lag + i]; + for (i = 0; i < Frame; i++) + DataBuff[i] = Buff[PitchMax + i] = mult (Buff[PitchMax + i], + (Word16) 0x6000); + } + else { + /* Unvoiced case */ + for (i = 0; i < Frame; i++) + DataBuff[i] = mult (Gain, Rand_lbc (Sd)); + /* Clear buffer to reset memory */ + for (i = 0; i < Frame + PitchMax; i++) + Buff[i] = (Word16) 0; + } + } + + return; +} + +/* +** +** Function: Comp_Lpf() +** +** Description: Computes pitch postfilter parameters. +** The pitch postfilter lag is first derived (Find_B +** and Find_F). Then, the one that gives the largest +** contribution is used to calculate the gains (Get_Ind). +** +** +** Links to text: Section 3.6 +** +** Arguments: +** +** Word16 *Buff decoded excitation +** Word16 Olp Decoded pitch lag +** Word16 Sfc Subframe index +** +** Outputs: +** +** +** Return value: +** +** PFDEF Pitch postfilter parameters: PF.Gain Pitch Postfilter gain +** PF.ScGn Pitch Postfilter scaling gain +** PF.Indx Pitch postfilter lag +*/ +PFDEF +Comp_Lpf (enum Crate WrkRate, Word16 * Buff, Word16 Olp, Word16 Sfc) +{ + int i, j; + + PFDEF Pf; + Word32 Lcr[5]; + Word16 Scr[5]; + Word16 Bindx, Findx; + Word16 Exp; + + Word32 Acc0, Acc1; + + /* Initialize */ + Pf.Indx = (Word16) 0; + Pf.Gain = (Word16) 0; + Pf.ScGn = (Word16) 0x7fff; + + /* Find both indices */ + Bindx = Find_B (Buff, Olp, Sfc); + Findx = Find_F (Buff, Olp, Sfc); + + /* Combine the results */ + if ((Bindx == (Word16) 0) && (Findx == (Word16) 0)) + return Pf; + + /* Compute target energy */ + Acc0 = (Word32) 0; + for (j = 0; j < SubFrLen; j++) + Acc0 = L_mac (Acc0, Buff[PitchMax + (int) Sfc * SubFrLen + j], + Buff[PitchMax + (int) Sfc * SubFrLen + j]); + Lcr[0] = Acc0; + + if (Bindx != (Word16) 0) { + Acc0 = (Word32) 0; + Acc1 = (Word32) 0; + for (j = 0; j < SubFrLen; j++) { + Acc0 = L_mac (Acc0, Buff[PitchMax + (int) Sfc * SubFrLen + j], + Buff[PitchMax + (int) Sfc * SubFrLen + (int) Bindx + j]); + Acc1 = + L_mac (Acc1, Buff[PitchMax + (int) Sfc * SubFrLen + (int) Bindx + j], + Buff[PitchMax + (int) Sfc * SubFrLen + (int) Bindx + j]); + } + Lcr[1] = Acc0; + Lcr[2] = Acc1; + } + else { + Lcr[1] = (Word32) 0; + Lcr[2] = (Word32) 0; + } + + if (Findx != (Word16) 0) { + Acc0 = (Word32) 0; + Acc1 = (Word32) 0; + for (j = 0; j < SubFrLen; j++) { + Acc0 = L_mac (Acc0, Buff[PitchMax + (int) Sfc * SubFrLen + j], + Buff[PitchMax + (int) Sfc * SubFrLen + (int) Findx + j]); + Acc1 = + L_mac (Acc1, Buff[PitchMax + (int) Sfc * SubFrLen + (int) Findx + j], + Buff[PitchMax + (int) Sfc * SubFrLen + (int) Findx + j]); + } + Lcr[3] = Acc0; + Lcr[4] = Acc1; + } + else { + Lcr[3] = (Word32) 0; + Lcr[4] = (Word32) 0; + } + + /* Normalize and convert to shorts */ + Acc1 = 0L; + for (i = 0; i < 5; i++) { + Acc0 = Lcr[i]; + if (Acc0 > Acc1) + Acc1 = Acc0; + } + + Exp = norm_l (Acc1); + for (i = 0; i < 5; i++) { + Acc0 = L_shl (Lcr[i], Exp); + Scr[i] = extract_h (Acc0); + } + + /* Select the best pair */ + if ((Bindx != (Word16) 0) && (Findx == (Word16) 0)) + Pf = Get_Ind (WrkRate, Bindx, Scr[0], Scr[1], Scr[2]); + + if ((Bindx == (Word16) 0) && (Findx != (Word16) 0)) + Pf = Get_Ind (WrkRate, Findx, Scr[0], Scr[3], Scr[4]); + + if ((Bindx != (Word16) 0) && (Findx != (Word16) 0)) { + Exp = mult_r (Scr[1], Scr[1]); + Acc0 = L_mult (Exp, Scr[4]); + Exp = mult_r (Scr[3], Scr[3]); + Acc1 = L_mult (Exp, Scr[2]); + if (Acc0 > Acc1) + Pf = Get_Ind (WrkRate, Bindx, Scr[0], Scr[1], Scr[2]); + else + Pf = Get_Ind (WrkRate, Findx, Scr[0], Scr[3], Scr[4]); + } + + return Pf; +} + +/* +** +** Function: Find_B() +** +** Description: Computes best pitch postfilter backward lag by +** backward cross correlation maximization around the +** decoded pitch lag +** of the subframe 0 (for subframes 0 & 1) +** of the subframe 2 (for subframes 2 & 3) +** +** Links to text: Section 3.6 +** +** Arguments: +** +** Word16 *Buff decoded excitation +** Word16 Olp Decoded pitch lag +** Word16 Sfc Subframe index +** +** Outputs: None +** +** Return value: +** +** Word16 Pitch postfilter backward lag +*/ +Word16 +Find_B (Word16 * Buff, Word16 Olp, Word16 Sfc) +{ + int i, j; + + Word16 Indx = 0; + + Word32 Acc0, Acc1; + + if (Olp > (Word16) (PitchMax - 3)) + Olp = (Word16) (PitchMax - 3); + + Acc1 = (Word32) 0; + + for (i = (int) Olp - 3; i <= (int) Olp + 3; i++) { + + Acc0 = (Word32) 0; + for (j = 0; j < SubFrLen; j++) + Acc0 = L_mac (Acc0, Buff[PitchMax + (int) Sfc * SubFrLen + j], + Buff[PitchMax + (int) Sfc * SubFrLen - i + j]); + if (Acc0 > Acc1) { + Acc1 = Acc0; + Indx = -(Word16) i; + } + } + return Indx; +} + +/* +** +** Function: Find_F() +** +** Description: Computes best pitch postfilter forward lag by +** forward cross correlation maximization around the +** decoded pitch lag +** of the subframe 0 (for subframes 0 & 1) +** of the subframe 2 (for subframes 2 & 3) +** +** Links to text: Section 3.6 +** +** Arguments: +** +** Word16 *Buff decoded excitation +** Word16 Olp Decoded pitch lag +** Word16 Sfc Subframe index +** +** Outputs: None +** +** Return value: +** +** Word16 Pitch postfilter forward lag +*/ +Word16 +Find_F (Word16 * Buff, Word16 Olp, Word16 Sfc) +{ + int i, j; + + Word16 Indx = 0; + + Word32 Acc0, Acc1; + + if (Olp > (Word16) (PitchMax - 3)) + Olp = (Word16) (PitchMax - 3); + + Acc1 = (Word32) 0; + + for (i = Olp - 3; i <= Olp + 3; i++) { + + Acc0 = (Word32) 0; + if (((int) Sfc * SubFrLen + SubFrLen + i) <= Frame) { + for (j = 0; j < SubFrLen; j++) + Acc0 = L_mac (Acc0, Buff[PitchMax + (int) Sfc * SubFrLen + j], + Buff[PitchMax + (int) Sfc * SubFrLen + i + j]); + } + + + if (Acc0 > Acc1) { + Acc1 = Acc0; + Indx = (Word16) i; + } + } + + return Indx; +} + +/* +** +** Function: Get_Ind() +** +** Description: Computes gains of the pitch postfilter. +** The gains are calculated using the cross correlation +** (forward or backward, the one with the greatest contribution) +** and the energy of the signal. Also, a test is performed on +** the prediction gain to see whether the pitch postfilter +** should be used or not. +** +** +** +** Links to text: Section 3.6 +** +** Arguments: +** +** Word16 Ind Pitch postfilter lag +** Word16 Ten energy of the current subframe excitation vector +** Word16 Ccr Crosscorrelation of the excitation +** Word16 Enr Energy of the (backward or forward) "delayed" excitation +** +** Outputs: None +** +** Return value: +** +** PFDEF +** Word16 Indx Pitch postfilter lag +** Word16 Gain Pitch postfilter gain +** Word16 ScGn Pitch postfilter scaling gain +** +*/ +PFDEF +Get_Ind (enum Crate WrkRate, Word16 Ind, Word16 Ten, Word16 Ccr, Word16 Enr) +{ + Word32 Acc0, Acc1; + Word16 Exp; + + PFDEF Pf; + + + Pf.Indx = Ind; + + /* Check valid gain */ + Acc0 = L_mult (Ten, Enr); + Acc0 = L_shr (Acc0, (Word16) 2); + Acc1 = L_mult (Ccr, Ccr); + + if (Acc1 > Acc0) { + + if (Ccr >= Enr) + Pf.Gain = LpfConstTable[(int) WrkRate]; + else { + Pf.Gain = div_s (Ccr, Enr); + Pf.Gain = mult (Pf.Gain, LpfConstTable[(int) WrkRate]); + } + /* Compute scaling gain */ + Acc0 = L_deposit_h (Ten); + Acc0 = L_shr (Acc0, (Word16) 1); + Acc0 = L_mac (Acc0, Ccr, Pf.Gain); + Exp = mult (Pf.Gain, Pf.Gain); + Acc1 = L_mult (Enr, Exp); + Acc1 = L_shr (Acc1, (Word16) 1); + Acc0 = L_add (Acc0, Acc1); + Exp = L_round (Acc0); + + Acc1 = L_deposit_h (Ten); + Acc0 = L_deposit_h (Exp); + Acc1 = L_shr (Acc1, (Word16) 1); + + if (Acc1 >= Acc0) + Exp = (Word16) 0x7fff; + else + Exp = div_l (Acc1, Exp); + + Acc0 = L_deposit_h (Exp); + Pf.ScGn = Sqrt_lbc (Acc0); + } + else { + Pf.Gain = (Word16) 0; + Pf.ScGn = (Word16) 0x7fff; + } + + Pf.Gain = mult (Pf.Gain, Pf.ScGn); + + return Pf; +} + +/* +** +** Function: Filt_Lpf() +** +** Description: Applies the pitch postfilter for each subframe. +** +** Links to text: Section 3.6 +** +** Arguments: +** +** Word16 *Tv Pitch postfiltered excitation +** Word16 *Buff decoded excitation +** PFDEF Pf Pitch postfilter parameters +** Word16 Sfc Subframe index +** +** Outputs: +** +** Word16 *Tv Pitch postfiltered excitation +** +** Return value: None +** +*/ +void +Filt_Lpf (Word16 * Tv, Word16 * Buff, PFDEF Pf, Word16 Sfc) +{ + int i; + + Word32 Acc0; + + for (i = 0; i < SubFrLen; i++) { + Acc0 = L_mult (Buff[PitchMax + (int) Sfc * SubFrLen + i], Pf.ScGn); + Acc0 = + L_mac (Acc0, Buff[PitchMax + (int) Sfc * SubFrLen + (int) Pf.Indx + i], + Pf.Gain); + Tv[(int) Sfc * SubFrLen + i] = L_round (Acc0); + } + + return; +} + +/* +** +** Function: ACELP_LBC_code() +** +** Description: Find Algebraic codebook for low bit rate LBC encoder +** +** Links to text: Section 2.16 +** +** Arguments: +** +** Word16 X[] Target vector. (in Q0) +** Word16 h[] Impulse response. (in Q12) +** Word16 T0 Pitch period. +** Word16 code[] Innovative vector. (in Q12) +** Word16 gain Innovative vector gain. (in Q0) +** Word16 sign Signs of the 4 pulses. +** Word16 shift Shift of the innovative vector +** Word16 gain_T0 Gain for pitch synchronous fiter +** +** Inputs : +** +** Word16 X[] Target vector. (in Q0) +** Word16 h[] Impulse response. (in Q12) +** Word16 T0 Pitch period. +** Word16 gain_T0 Gain for pitch synchronous fiter +** +** Outputs: +** +** Word16 code[] Innovative vector. (in Q12) +** Word16 gain Innovative vector gain. (in Q0) +** Word16 sign Signs of the 4 pulses. +** Word16 shift Shift of the innovative vector. +** +** Return value: +** +** Word16 index Innovative codebook index +** +*/ +Word16 +ACELP_LBC_code (Word16 X[], Word16 h[], Word16 T0, Word16 code[], + Word16 * ind_gain, Word16 * shift, Word16 * sign, + Word16 gain_T0) +{ + Word16 i, index, gain_q; + Word16 Dn[SubFrLen2], tmp_code[SubFrLen2]; + Word16 rr[DIM_RR]; + + /* + * Include fixed-gain pitch contribution into impulse resp. h[] + * Find correlations of h[] needed for the codebook search. + */ + for (i = 0; i < SubFrLen; i++) /* Q13 --> Q12 */ + h[i] = shr (h[i], 1); + + if (T0 < SubFrLen - 2) { + for (i = T0; i < SubFrLen; i++) /* h[i] += gain_T0*h[i-T0] */ + h[i] = add (h[i], mult (h[i - T0], gain_T0)); + } + + Cor_h (h, rr); + + /* + * Compute correlation of target vector with impulse response. + */ + + Cor_h_X (h, X, Dn); + + /* + * Find innovative codebook. + * rr input matrix autocorrelation + * output filtered codeword + */ + + index = D4i64_LBC (Dn, rr, h, tmp_code, rr, shift, sign); + + /* + * Compute innovation vector gain. + * Include fixed-gain pitch contribution into code[]. + */ + + *ind_gain = G_code (X, rr, &gain_q); + + for (i = 0; i < SubFrLen; i++) { + code[i] = i_mult (tmp_code[i], gain_q); + } + + if (T0 < SubFrLen - 2) + for (i = T0; i < SubFrLen; i++) /* code[i] += gain_T0*code[i-T0] */ + code[i] = add (code[i], mult (code[i - T0], gain_T0)); + + + return index; +} + +/* +** +** Function: Cor_h() +** +** Description: Compute correlations of h[] needed for the codebook search. +** +** Links to text: Section 2.16 +** +** Arguments: +** +** Word16 h[] Impulse response. +** Word16 rr[] Correlations. +** +** Outputs: +** +** Word16 rr[] Correlations. +** +** Return value : None +*/ +void +Cor_h (Word16 * H, Word16 * rr) +{ + Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3; + Word16 *rri0i1, *rri0i2, *rri0i3; + Word16 *rri1i2, *rri1i3, *rri2i3; + + Word16 *p0, *p1, *p2, *p3; + + Word16 *ptr_hd, *ptr_hf, *ptr_h1, *ptr_h2; + Word32 cor; + Word16 i, k, ldec, l_fin_sup, l_fin_inf; + Word16 h[SubFrLen2]; + + /* Scaling for maximum precision */ + + cor = 0; + for (i = 0; i < SubFrLen; i++) + cor = L_mac (cor, H[i], H[i]); + + if (extract_h (cor) > 32000) { + for (i = 0; i < SubFrLen; i++) + h[i + 4] = shr (H[i], 1); + } + else { + k = norm_l (cor); + k = shr (k, 1); + for (i = 0; i < SubFrLen; i++) + h[i + 4] = shl (H[i], k); + } + + for (i = 0; i < 4; i++) + h[i] = 0; + + /* Init pointers */ + + rri0i0 = rr; + rri1i1 = rri0i0 + NB_POS; + rri2i2 = rri1i1 + NB_POS; + rri3i3 = rri2i2 + NB_POS; + + rri0i1 = rri3i3 + NB_POS; + rri0i2 = rri0i1 + MSIZE; + rri0i3 = rri0i2 + MSIZE; + rri1i2 = rri0i3 + MSIZE; + rri1i3 = rri1i2 + MSIZE; + rri2i3 = rri1i3 + MSIZE; + + /* + * Compute rri0i0[], rri1i1[], rri2i2[] and rri3i3[] + */ + + p0 = rri0i0 + NB_POS - 1; /* Init pointers to last position of rrixix[] */ + p1 = rri1i1 + NB_POS - 1; + p2 = rri2i2 + NB_POS - 1; + p3 = rri3i3 + NB_POS - 1; + + ptr_h1 = h; + cor = 0; + for (i = 0; i < NB_POS; i++) { + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p3-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p2-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p1-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p0-- = extract_h (cor); + } + + + /* + * Compute elements of: rri0i1[], rri0i3[], rri1i2[] and rri2i3[] + */ + + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + ldec = NB_POS + 1; + + ptr_hd = h; + ptr_hf = ptr_hd + 2; + + for (k = 0; k < NB_POS; k++) { + + p3 = rri2i3 + l_fin_sup; + p2 = rri1i2 + l_fin_sup; + p1 = rri0i1 + l_fin_sup; + p0 = rri0i3 + l_fin_inf; + cor = 0; + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /* + * Compute elements of: rri0i2[], rri1i3[] + */ + + ptr_hd = h; + ptr_hf = ptr_hd + 4; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + p3 = rri1i3 + l_fin_sup; + p2 = rri0i2 + l_fin_sup; + p1 = rri1i3 + l_fin_inf; + p0 = rri0i2 + l_fin_inf; + + cor = 0; + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + for (i = k + (Word16) 1; i < NB_POS; i++) { + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /* + * Compute elements of: rri0i1[], rri0i3[], rri1i2[] and rri2i3[] + */ + + ptr_hd = h; + ptr_hf = ptr_hd + 6; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p3 = rri0i3 + l_fin_sup; + p2 = rri2i3 + l_fin_inf; + p1 = rri1i2 + l_fin_inf; + p0 = rri0i1 + l_fin_inf; + + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + cor = 0; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + return; +} + +/* +** +** Function: Corr_h_X() +** +** Description: Compute correlations of input response h[] with +** the target vector X[]. +** +** Links to the text: Section 2.16 +** +** Arguments: +** +** Word16 h[] Impulse response. +** Word16 X[] Target vector. +** Word16 D[] Correlations. +** +** Outputs: +** +** Word16 D[] Correlations. +** +** Return value: None +*/ +void +Cor_h_X (Word16 h[], Word16 X[], Word16 D[]) +{ + Word16 i, j; + Word32 s, max; + Word32 y32[SubFrLen]; + + /* first keep the result on 32 bits and find absolute maximum */ + + max = 0; + + for (i = 0; i < SubFrLen; i++) { + s = 0; + for (j = i; j < SubFrLen; j++) + s = L_mac (s, X[j], h[j - i]); + + y32[i] = s; + + s = L_abs (s); + if (s > max) + max = s; + } + + /* + * Find the number of right shifts to do on y32[] + * so that maximum is on 13 bits + */ + + j = norm_l (max); + if (sub (j, 16) > 0) + j = 16; + + j = sub (18, j); + + for (i = 0; i < SubFrLen; i++) + D[i] = extract_l (L_shr (y32[i], j)); + + return; +} + +/* +** Function: Reset_max_time() +** +** Description: This function should be called at the beginning +** of each frame. +** +** Links to the text: Section 2.16 +** +** Arguments: None +** +** Inputs: None +** +** Outputs: +** +** Word16 extra +** +** Return value: None +** +*/ +static Word16 extra; +void +reset_max_time (void) +{ + extra = 120; + return; +} + +/* +** +** Function: D4i64_LBC +** +** Description: Algebraic codebook for LBC. +** -> 17 bits; 4 pulses in a frame of 60 samples +** +** The code length is 60, containing 4 nonzero pulses +** i0, i1, i2, i3. Each pulse can have 8 possible +** positions (positive or negative): +** +** i0 (+-1) : 0, 8, 16, 24, 32, 40, 48, 56 +** i1 (+-1) : 2, 10, 18, 26, 34, 42, 50, 58 +** i2 (+-1) : 4, 12, 20, 28, 36, 44, 52, (60) +** i3 (+-1) : 6, 14, 22, 30, 38, 46, 54, (62) +** +** All the pulse can be shifted by one. +** The last position of the last 2 pulses falls outside the +** frame and signifies that the pulse is not present. +** The threshold controls if a section of the innovative +** codebook should be searched or not. +** +** Links to the text: Section 2.16 +** +** Input arguments: +** +** Word16 Dn[] Correlation between target vector and impulse response h[] +** Word16 rr[] Correlations of impulse response h[] +** Word16 h[] Impulse response of filters +** +** Output arguments: +** +** Word16 cod[] Selected algebraic codeword +** Word16 y[] Filtered codeword +** Word16 code_shift Shift of the codeword +** Word16 sign Signs of the 4 pulses. +** +** Return value: +** +** Word16 Index of selected codevector +** +*/ +Word16 +D4i64_LBC (Word16 Dn[], Word16 rr[], Word16 h[], Word16 cod[], + Word16 y[], Word16 * code_shift, Word16 * sign) +{ + Word16 i0, i1, i2, i3, ip0, ip1, ip2, ip3; + Word16 i, j, time; + Word16 shif, shift; + Word16 ps0, ps1, ps2, ps3, alp, alp0; + Word32 alp1, alp2, alp3, L32; + Word16 ps0a, ps1a, ps2a; + Word16 ps3c, psc, alpha; + Word16 means, max0, max1, max2, thres; + + Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3; + Word16 *rri0i1, *rri0i2, *rri0i3; + Word16 *rri1i2, *rri1i3, *rri2i3; + + Word16 *ptr_ri0i0, *ptr_ri1i1, *ptr_ri2i2, *ptr_ri3i3; + Word16 *ptr_ri0i1, *ptr_ri0i2, *ptr_ri0i3; + Word16 *ptr_ri1i2, *ptr_ri1i3, *ptr_ri2i3; + + Word16 *ptr1_ri0i1, *ptr1_ri0i2, *ptr1_ri0i3; + Word16 *ptr1_ri1i2, *ptr1_ri1i3, *ptr1_ri2i3; + + Word16 p_sign[SubFrLen2 / 2]; + + /* Init pointers */ + + rri0i0 = rr; + rri1i1 = rri0i0 + NB_POS; + rri2i2 = rri1i1 + NB_POS; + rri3i3 = rri2i2 + NB_POS; + + rri0i1 = rri3i3 + NB_POS; + rri0i2 = rri0i1 + MSIZE; + rri0i3 = rri0i2 + MSIZE; + rri1i2 = rri0i3 + MSIZE; + rri1i3 = rri1i2 + MSIZE; + rri2i3 = rri1i3 + MSIZE; + + /* + * Extend the backward filtered target vector by zeros + */ + + for (i = SubFrLen; i < SubFrLen2; i++) + Dn[i] = 0; + + /* + * Chose the sign of the impulse. + */ + + for (i = 0; i < SubFrLen; i += 2) { + if (add (Dn[i], Dn[i + 1]) >= 0) { + p_sign[i / 2] = 1; + } + else { + p_sign[i / 2] = -1; + Dn[i] = -Dn[i]; + Dn[i + 1] = -Dn[i + 1]; + } + } + p_sign[30] = p_sign[31] = 1; + + /* + * Compute the search threshold after three pulses + */ + + /* odd positions */ + /* Find maximum of Dn[i0]+Dn[i1]+Dn[i2] */ + + max0 = Dn[0]; + max1 = Dn[2]; + max2 = Dn[4]; + for (i = 8; i < SubFrLen; i += STEP) { + if (Dn[i] > max0) + max0 = Dn[i]; + if (Dn[i + 2] > max1) + max1 = Dn[i + 2]; + if (Dn[i + 4] > max2) + max2 = Dn[i + 4]; + } + max0 = add (max0, max1); + max0 = add (max0, max2); + + /* Find means of Dn[i0]+Dn[i1]+Dn[i2] */ + + L32 = 0; + for (i = 0; i < SubFrLen; i += STEP) { + L32 = L_mac (L32, Dn[i], 1); + L32 = L_mac (L32, Dn[i + 2], 1); + L32 = L_mac (L32, Dn[i + 4], 1); + } + means = extract_l (L_shr (L32, 4)); + + /* thres = means + (max0-means)*threshold; */ + + thres = sub (max0, means); + thres = mult (thres, threshold); + thres = add (thres, means); + + /* even positions */ + /* Find maximum of Dn[i0]+Dn[i1]+Dn[i2] */ + + max0 = Dn[1]; + max1 = Dn[3]; + max2 = Dn[5]; + for (i = 9; i < SubFrLen; i += STEP) { + if (Dn[i] > max0) + max0 = Dn[i]; + if (Dn[i + 2] > max1) + max1 = Dn[i + 2]; + if (Dn[i + 4] > max2) + max2 = Dn[i + 4]; + } + max0 = add (max0, max1); + max0 = add (max0, max2); + + /* Find means of Dn[i0]+Dn[i1]+Dn[i2] */ + + L32 = 0; + for (i = 1; i < SubFrLen; i += STEP) { + L32 = L_mac (L32, Dn[i], 1); + L32 = L_mac (L32, Dn[i + 2], 1); + L32 = L_mac (L32, Dn[i + 4], 1); + } + means = extract_l (L_shr (L32, 4)); + + + /* max1 = means + (max0-means)*threshold */ + + max1 = sub (max0, means); + max1 = mult (max1, threshold); + max1 = add (max1, means); + + /* Keep maximum threshold between odd and even position */ + + if (max1 > thres) + thres = max1; + + /* + * Modification of rrixiy[] to take signs into account. + */ + + ptr_ri0i1 = rri0i1; + ptr_ri0i2 = rri0i2; + ptr_ri0i3 = rri0i3; + ptr1_ri0i1 = rri0i1; + ptr1_ri0i2 = rri0i2; + ptr1_ri0i3 = rri0i3; + + for (i0 = 0; i0 < SubFrLen / 2; i0 += STEP / 2) { + for (i1 = 2 / 2; i1 < SubFrLen / 2; i1 += STEP / 2) { + *ptr_ri0i1++ = i_mult (*ptr1_ri0i1++, i_mult (p_sign[i0], p_sign[i1])); + *ptr_ri0i2++ = i_mult (*ptr1_ri0i2++, + i_mult (p_sign[i0], p_sign[i1 + 1])); + *ptr_ri0i3++ = i_mult (*ptr1_ri0i3++, + i_mult (p_sign[i0], p_sign[i1 + 2])); + } + } + + ptr_ri1i2 = rri1i2; + ptr_ri1i3 = rri1i3; + ptr1_ri1i2 = rri1i2; + ptr1_ri1i3 = rri1i3; + for (i1 = 2 / 2; i1 < SubFrLen / 2; i1 += STEP / 2) { + for (i2 = 4 / 2; i2 < SubFrLen2 / 2; i2 += STEP / 2) { + *ptr_ri1i2++ = i_mult (*ptr1_ri1i2++, i_mult (p_sign[i1], p_sign[i2])); + *ptr_ri1i3++ = i_mult (*ptr1_ri1i3++, + i_mult (p_sign[i1], p_sign[i2 + 1])); + + } + } + + ptr_ri2i3 = rri2i3; + + ptr1_ri2i3 = rri2i3; + for (i2 = 4 / 2; i2 < SubFrLen2 / 2; i2 += STEP / 2) { + for (i3 = 6 / 2; i3 < SubFrLen2 / 2; i3 += STEP / 2) + *ptr_ri2i3++ = i_mult (*ptr1_ri2i3++, i_mult (p_sign[i2], p_sign[i3])); + } + + /* + * Search the optimum positions of the four pulses which maximize + * square(correlation) / energy + * The search is performed in four nested loops. At each loop, one + * pulse contribution is added to the correlation and energy. + * + * The fourth loop is entered only if the correlation due to the + * contribution of the first three pulses exceeds the preset + * threshold. + */ + + /* Default values */ + ip0 = 0; + ip1 = 2; + ip2 = 4; + ip3 = 6; + shif = 0; + psc = 0; + alpha = 32767; + time = add (max_time, extra); + + + + /* Four loops to search innovation code. */ + + /* Init. pointers that depend on first loop */ + ptr_ri0i0 = rri0i0; + ptr_ri0i1 = rri0i1; + ptr_ri0i2 = rri0i2; + ptr_ri0i3 = rri0i3; + + /* first pulse loop */ + for (i0 = 0; i0 < SubFrLen; i0 += STEP) { + + ps0 = Dn[i0]; + ps0a = Dn[i0 + 1]; + alp0 = *ptr_ri0i0++; + + /* Init. pointers that depend on second loop */ + ptr_ri1i1 = rri1i1; + ptr_ri1i2 = rri1i2; + ptr_ri1i3 = rri1i3; + + /* second pulse loop */ + for (i1 = 2; i1 < SubFrLen; i1 += STEP) { + + ps1 = add (ps0, Dn[i1]); + ps1a = add (ps0a, Dn[i1 + 1]); + + /* alp1 = alp0 + *ptr_ri1i1++ + 2.0 * ( *ptr_ri0i1++); */ + + alp1 = L_mult (alp0, 1); + alp1 = L_mac (alp1, *ptr_ri1i1++, 1); + alp1 = L_mac (alp1, *ptr_ri0i1++, 2); + + /* Init. pointers that depend on third loop */ + ptr_ri2i2 = rri2i2; + ptr_ri2i3 = rri2i3; + + /* third pulse loop */ + for (i2 = 4; i2 < SubFrLen2; i2 += STEP) { + + ps2 = add (ps1, Dn[i2]); + ps2a = add (ps1a, Dn[i2 + 1]); + + /* alp2 = alp1 + *ptr_ri2i2++ + + 2.0 * (*ptr_ri0i2++ + *ptr_ri1i2++); */ + + alp2 = L_mac (alp1, *ptr_ri2i2++, 1); + alp2 = L_mac (alp2, *ptr_ri0i2++, 2); + alp2 = L_mac (alp2, *ptr_ri1i2++, 2); + + /* Decide the shift */ + + shift = 0; + if (ps2a > ps2) { + shift = 1; + ps2 = ps2a; + } + + /* Test threshold */ + + if (ps2 > thres) { + + /* Init. pointers that depend on 4th loop */ + ptr_ri3i3 = rri3i3; + + /* 4th pulse loop */ + for (i3 = 6; i3 < SubFrLen2; i3 += STEP) { + + ps3 = add (ps2, Dn[i3 + shift]); + + /* alp3 = alp2 + (*ptr_ri3i3++) + + 2 x ( (*ptr_ri0i3++) + + (*ptr_ri1i3++) + + (*ptr_ri2i3++) ) */ + + alp3 = L_mac (alp2, *ptr_ri3i3++, 1); + alp3 = L_mac (alp3, *ptr_ri0i3++, 2); + alp3 = L_mac (alp3, *ptr_ri1i3++, 2); + alp3 = L_mac (alp3, *ptr_ri2i3++, 2); + alp = extract_l (L_shr (alp3, 5)); + + ps3c = mult (ps3, ps3); + if (L_mult (ps3c, alpha) > L_mult (psc, alp)) { + psc = ps3c; + alpha = alp; + ip0 = i0; + ip1 = i1; + ip2 = i2; + ip3 = i3; + shif = shift; + } + } /* end of for i3 = */ + + time--; + if (time <= 0) + goto end_search; /* Max time finish */ + ptr_ri0i3 -= NB_POS; + ptr_ri1i3 -= NB_POS; + + } /* end of if >thres */ + + else { + ptr_ri2i3 += NB_POS; + } + + } /* end of for i2 = */ + + ptr_ri0i2 -= NB_POS; + ptr_ri1i3 += NB_POS; + + } /* end of for i1 = */ + + ptr_ri0i2 += NB_POS; + ptr_ri0i3 += NB_POS; + + } /* end of for i0 = */ + +end_search: + + extra = time; + + /* Set the sign of impulses */ + + i0 = p_sign[shr (ip0, 1)]; + i1 = p_sign[shr (ip1, 1)]; + i2 = p_sign[shr (ip2, 1)]; + i3 = p_sign[shr (ip3, 1)]; + + /* Find the codeword corresponding to the selected positions */ + + for (i = 0; i < SubFrLen; i++) + cod[i] = 0; + + if (shif > 0) { + ip0 = add (ip0, 1); + ip1 = add (ip1, 1); + ip2 = add (ip2, 1); + ip3 = add (ip3, 1); + } + + cod[ip0] = i0; + cod[ip1] = i1; + if (ip2 < SubFrLen) + cod[ip2] = i2; + if (ip3 < SubFrLen) + cod[ip3] = i3; + + /* find the filtered codeword */ + + for (i = 0; i < SubFrLen; i++) + y[i] = 0; + + if (i0 > 0) + for (i = ip0, j = 0; i < SubFrLen; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip0, j = 0; i < SubFrLen; i++, j++) + y[i] = sub (y[i], h[j]); + + if (i1 > 0) + for (i = ip1, j = 0; i < SubFrLen; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip1, j = 0; i < SubFrLen; i++, j++) + y[i] = sub (y[i], h[j]); + + if (ip2 < SubFrLen) { + + if (i2 > 0) + for (i = ip2, j = 0; i < SubFrLen; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip2, j = 0; i < SubFrLen; i++, j++) + y[i] = sub (y[i], h[j]); + } + + if (ip3 < SubFrLen) { + + if (i3 > 0) + for (i = ip3, j = 0; i < SubFrLen; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip3, j = 0; i < SubFrLen; i++, j++) + y[i] = sub (y[i], h[j]); + } + + /* find codebook index; 17-bit address */ + + *code_shift = shif; + + *sign = 0; + if (i0 > 0) + *sign = add (*sign, 1); + if (i1 > 0) + *sign = add (*sign, 2); + if (i2 > 0) + *sign = add (*sign, 4); + if (i3 > 0) + *sign = add (*sign, 8); + + i = shr (ip0, 3); + i = add (i, shl (shr (ip1, 3), 3)); + i = add (i, shl (shr (ip2, 3), 6)); + i = add (i, shl (shr (ip3, 3), 9)); + + return i; +} + +/* +** +** Function: G_code() +** +** Description: Compute the gain of innovative code. +** +** +** Links to the text: Section 2.16 +** +** Input arguments: +** +** Word16 X[] Code target. (in Q0) +** Word16 Y[] Filtered innovation code. (in Q12) +** +** Output: +** +** Word16 *gain_q Gain of innovation code. (in Q0) +** +** Return value: +** +** Word16 index of innovation code gain +** +*/ +Word16 +G_code (Word16 X[], Word16 Y[], Word16 * gain_q) +{ + Word16 i; + Word16 xy, yy, exp_xy, exp_yy, gain, gain_nq; + Word32 L_xy, L_yy; + Word16 dist, dist_min; + + + /* Scale down Y[] by 8 to avoid overflow */ + for (i = 0; i < SubFrLen; i++) + Y[i] = shr (Y[i], 3); + + /* Compute scalar product */ + L_xy = 0L; + for (i = 0; i < SubFrLen; i++) + L_xy = L_mac (L_xy, X[i], Y[i]); + + exp_xy = norm_l (L_xy); + xy = extract_h (L_shl (L_xy, exp_xy)); + + if (xy <= 0) { + gain = 0; + *gain_q = FcbkGainTable[gain]; + return (gain); + } + + /* Compute scalar product */ + L_yy = 0L; + for (i = 0; i < SubFrLen; i++) + L_yy = L_mac (L_yy, Y[i], Y[i]); + + exp_yy = norm_l (L_yy); + yy = extract_h (L_shl (L_yy, exp_yy)); + + /* compute gain = xy/yy */ + xy = shr (xy, 1); /* Be sure xy < yy */ + gain_nq = div_s (xy, yy); + + i = add (exp_xy, 5); /* Denormalization of division */ + i = sub (i, exp_yy); + + gain_nq = shr (gain_nq, i); + + gain = (Word16) 0; + dist_min = sub (gain_nq, FcbkGainTable[0]); + dist_min = abs_s (dist_min); + for (i = 1; i < NumOfGainLev; i++) { + dist = sub (gain_nq, FcbkGainTable[i]); + dist = abs_s (dist); + if (dist < dist_min) { + dist_min = dist; + gain = (Word16) i; + } + } + *gain_q = FcbkGainTable[gain]; + + return (gain); +} + +/* +** +** Function: search_T0() +** +** Description: Gets parameters of pitch synchronous filter +** +** Links to the text: Section 2.16 +** +** Arguments: +** +** Word16 T0 Decoded pitch lag +** Word16 Gid Gain vector index in the adaptive gain vector codebook +** Word16 *gain_T0 Pitch synchronous gain +** +** Outputs: +** +** Word16 *gain_T0 Pitch synchronous filter gain +** +** Return Value: +** +** Word16 T0_mod Pitch synchronous filter lag +*/ +Word16 +search_T0 (Word16 T0, Word16 Gid, Word16 * gain_T0) +{ + + Word16 T0_mod; + + T0_mod = T0 + epsi170[Gid]; + *gain_T0 = gain170[Gid]; + + return (T0_mod); +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/exc_lbc.h asterisk-1.2.1/codecs/g723_1/exc_lbc.h --- asterisk-1.2.1.ori/codecs/g723_1/exc_lbc.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/exc_lbc.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,48 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "exc_lbc.h" +** +** Description: Function prototypes for "exc_lbc.c" +** +*/ + +#include "coder.h" + +Word16 Estim_Pitch (Word16 * Dpnt, Word16 Start); +PWDEF Comp_Pw (Word16 * Dpnt, Word16 Start, Word16 Olp); +void Filt_Pw (Word16 * DataBuff, Word16 * Dpnt, Word16 Start, PWDEF Pw); +void Find_Fcbk (enum Crate WrkRate, Word16 * Dpnt, Word16 * ImpResp, + LINEDEF * Line, Word16 Sfc); +void Gen_Trn (Word16 * Dst, Word16 * Src, Word16 Olp); +void Find_Best (BESTDEF * Best, Word16 * Tv, Word16 * ImpResp, Word16 Np, + Word16 Olp); +void Fcbk_Pack (Word16 * Dpnt, SFSDEF * Sfs, BESTDEF * Best, Word16 Np); +void Fcbk_Unpk (enum Crate WrkRate, Word16 * Tv, SFSDEF Sfs, Word16 Olp, + Word16 Sfc); +void Find_Acbk (CODSTATDEF * CodStat, Word16 * Tv, Word16 * ImpResp, + Word16 * PrevExc, LINEDEF * Line, Word16 Sfc); +void Get_Rez (Word16 * Tv, Word16 * PrevExc, Word16 Lag); +void Decod_Acbk (enum Crate WrkRate, Word16 * Tv, Word16 * PrevExc, + Word16 Olp, Word16 Lid, Word16 Gid); +Word16 Comp_Info (Word16 * Buff, Word16 Olp, Word16 * Gain, Word16 * ShGain); +void Regen (Word16 * DataBuff, Word16 * Buff, Word16 Lag, Word16 Gain, + Word16 Ecount, Word16 * Sd); +PFDEF Comp_Lpf (enum Crate WrkRate, Word16 * Buff, Word16 Olp, Word16 Sfc); +Word16 Find_B (Word16 * Buff, Word16 Olp, Word16 Sfc); +Word16 Find_F (Word16 * Buff, Word16 Olp, Word16 Sfc); +PFDEF Get_Ind (enum Crate WrkRate, Word16 Ind, Word16 Ten, Word16 Ccr, + Word16 Enr); +void Filt_Lpf (Word16 * Tv, Word16 * Buff, PFDEF Pf, Word16 Sfc); +void reset_max_time (void); +Word16 search_T0 (Word16 T0, Word16 Gid, Word16 * gain_T0); +Word16 ACELP_LBC_code (Word16 X[], Word16 h[], Word16 T0, Word16 code[], + Word16 * gain, Word16 * shift, Word16 * sign, + Word16 gain_T0); +void Cor_h (Word16 * H, Word16 * rr); +void Cor_h_X (Word16 h[], Word16 X[], Word16 D[]); +Word16 D4i64_LBC (Word16 Dn[], Word16 rr[], Word16 h[], Word16 cod[], + Word16 y[], Word16 * code_shift, Word16 * sign); +Word16 G_code (Word16 X[], Word16 Y[], Word16 * gain_q); diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/lbccodec.c asterisk-1.2.1/codecs/g723_1/lbccodec.c --- asterisk-1.2.1.ori/codecs/g723_1/lbccodec.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/lbccodec.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,333 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "lbccodec.c" +** +** Description: Top-level source code for G.723 dual-rate codec +** +** Functions: main +** Process_files() +** +** +*/ + +#include +#include +#include +#include + +#include "typedef.h" +#include "basop.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "coder.h" +#include "decod.h" +#include "exc_lbc.h" +#include "util_lbc.h" +#include "cod_cng.h" +#include "vad.h" + +/* Global variables */ +enum Wmode WrkMode = Both; +enum Crate WrkRate = Rate63; + +int PackedFrameSize[2] = { + 24, + 20 +}; + +Flag UseHp = True; +Flag UsePf = True; +Flag UseVx = False; +Flag UsePr = True; + +char SignOn[] = "ACL/USH/FT/DSPG ANSI C CODEC ITU LBC Ver 5.00\n"; + +static long Process_Files (FILE ** Ifp, FILE ** Ofp, FILE ** Fep, + FILE ** Ratp, int Argc, char *Argv[]); + +int +main (int argc, char *argv[]) +{ + DECSTATDEF *DecStat; + CODSTATDEF *CodStat; + FILE *Ifp, *Ofp; /* I/O File pointers */ + FILE *Fep = NULL; /* Frame erasures file pointer */ + FILE *Ratp = NULL; /* Rate file pointer */ + + long FrCnt = 0; + long FlLen; + + Word16 DataBuff[Frame]; + Word16 Crc; + char Rate_Rd; + + char Line[24]; + + printf ("%s", SignOn); + + /* Process arguments and open I/O files */ + FlLen = Process_Files (&Ifp, &Ofp, &Fep, &Ratp, argc, argv); + + /* + Init coder and the decoder + */ + CodStat = Init_Coder (UseVx, UseHp, WrkRate); + DecStat = Init_Decod (UsePf, WrkRate); + + /* Process all the input file */ + do { + + switch (WrkMode) { + + case Both: + if (Ratp != NULL) { + fread ((char *) &Rate_Rd, sizeof (char), 1, Ratp); + WrkRate = (enum Crate) Rate_Rd; + } + if (WrkRate == Rate53) + reset_max_time (); + Read_lbc (DataBuff, Frame, Ifp); + Coder (CodStat, DataBuff, Line); + Decod (DecStat, DataBuff, Line, (Word16) 0); + Write_lbc (DataBuff, Frame, Ofp); + break; + + case Cod: + if (Ratp != NULL) { + fread ((char *) &Rate_Rd, sizeof (char), 1, Ratp); + WrkRate = (enum Crate) Rate_Rd; + } + if (WrkRate == Rate53) + reset_max_time (); + Read_lbc (DataBuff, Frame, Ifp); + Coder (CodStat, DataBuff, Line); + Line_Wr (Line, Ofp); + break; + + case Dec: + if (Line_Rd (Line, Ifp) == (-1)) { + FlLen = FrCnt; + break; + } + if (Fep == NULL) + Crc = (Word16) 0; + else + fread ((char *) &Crc, sizeof (Word16), 1, Fep); + Decod (DecStat, DataBuff, Line, Crc); + Write_lbc (DataBuff, Frame, Ofp); + break; + } + + FrCnt++; + if (UsePr) { + if (WrkMode == Dec) { + if (FrCnt < FlLen) { + fprintf (stdout, "Done : %6ld\r", FrCnt); + } + } + else { + fprintf (stdout, "Done : %6ld %3ld\r", FrCnt, FrCnt * 100 / FlLen); + } + fflush (stdout); + } + + } while (FrCnt < FlLen); + + if (Ifp) { + (void) fclose (Ifp); + } + if (Ofp) { + (void) fclose (Ofp); + } + if (Fep) { + (void) fclose (Fep); + } + if (Ratp) { + (void) fclose (Ratp); + } + return 0; +} + + +/* + This function processes the argument parameters. The function + opens the IO files, and sets the global arguments accordingly + to the command line parameters. +*/ +long +Process_Files (FILE ** Ifp, FILE ** Ofp, FILE ** Fep, FILE ** Ratp, + int Argc, char *Argv[]) +{ + int i; + long Flen; + char *FerFileName = NULL; + char *RateFileName = NULL; + + /* + Process the argument list, if any + */ + if (Argc < 3) { + printf ("Usage: %s [options] inputfile outputfile \n", Argv[0]); + exit (1); + } + + for (i = 1; i < Argc - 2; i++) { + + /* Check the coder rate */ + if (!strncmp ("-r", Argv[i], 2)) { + if (!strcmp ("63", Argv[i] + 2)) { + WrkRate = Rate63; + continue; + } + + else if (!strcmp ("53", Argv[i] + 2)) { + WrkRate = Rate53; + continue; + } + + else { + RateFileName = &Argv[i][2]; + continue; + } + } + + /* Check Working mode */ + if (!strcmp ("-b", Argv[i])) { + WrkMode = Both; + continue; + } + + if (!strcmp ("-c", Argv[i])) { + WrkMode = Cod; + continue; + } + + if (!strcmp ("-d", Argv[i])) { + WrkMode = Dec; + continue; + } + + if (!strcmp ("-v", Argv[i])) { + UseVx = True; + continue; + } + + if (!strcmp ("-Noh", Argv[i])) { + UseHp = False; + continue; + } + + if (!strcmp ("-Nop", Argv[i])) { + UsePf = False; + continue; + } + + if (!strncmp ("-f", Argv[i], 2)) { + FerFileName = &Argv[i][2]; + continue; + } + + if (!strcmp ("-n", Argv[i])) { + UsePr = False; + continue; + } + + fprintf (stderr, "Illegal argument, %s\n", Argv[i]); + exit (1); + } + + *Ifp = fopen (Argv[Argc - 2], "rb"); + if (*Ifp == NULL) { + fprintf (stderr, "Invalid input file name: %s\n", Argv[Argc - 2]); + exit (1); + } + + if (UsePr) + printf ("Input file: %s\n", Argv[Argc - 2]); + + *Ofp = fopen (Argv[Argc - 1], "wb"); + if (*Ofp == NULL) { + fprintf (stderr, "Can't open output file: %s\n", Argv[Argc - 1]); + exit (1); + } + if (UsePr) + printf ("Output file: %s\n", Argv[Argc - 1]); + + /* Open Fer file if required */ + if (WrkMode == Dec) { + + if (FerFileName != NULL) { + *Fep = fopen (FerFileName, "rb"); + if (*Fep == NULL) { + fprintf (stderr, "Can't open FER file: %s\n", FerFileName); + exit (1); + } + if (UsePr) + printf ("FER file: %s\n", FerFileName); + } + } + else { + if (RateFileName != NULL) { + *Ratp = fopen (RateFileName, "rb"); + if (*Ratp == NULL) { + fprintf (stderr, "Can't open Rate file: %s\n", RateFileName); + exit (1); + } + if (UsePr) + printf ("Rate file: %s\n", RateFileName); + } + } + + /* Options report */ + if (UsePr) { + + printf ("Options:\n"); + if (WrkMode == Both) + printf ("Encoder/Decoder\n"); + else if (WrkMode == Cod) + printf ("Encoder\n"); + else + printf ("Decoder\n"); + + + if (WrkMode != Cod) { + if (UsePf == 0) + printf ("Postfilter disabled\n"); + else + printf ("Postfilter enabled\n"); + } + + if (WrkMode <= Cod) { + if (*Ratp == NULL) { + if (WrkRate == Rate63) + printf ("Rate 6.3 kb/s\n"); + else + printf ("Rate 5.3 kb/s\n"); + } + if (UseHp == 0) + printf ("Highpassfilter disabled\n"); + else + printf ("Highpassfilter enabled\n"); + if (UseVx == 0) + printf ("VAD/CNG disabled\n"); + else + printf ("VAD/CNG enabled\n"); + } + } + + /* + Compute the file length + */ + fseek (*Ifp, 0L, SEEK_END); + Flen = ftell (*Ifp); + rewind (*Ifp); + if (WrkMode == Dec) + Flen = 0x7fffffffL; + else + Flen /= sizeof (Word16) * Frame; + + return Flen; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/lpc.c asterisk-1.2.1/codecs/g723_1/lpc.c --- asterisk-1.2.1.ori/codecs/g723_1/lpc.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/lpc.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,989 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: lpc.c +** +** Description: Functions that implement linear predictive coding +** (LPC) operations. +** +** Functions: +** +** Computing LPC coefficients: +** +** Comp_Lpc() +** Durbin() +** +** Perceptual noise weighting: +** +** Wght_Lpc() +** Error_Wght() +** +** Computing combined impulse response: +** +** Comp_Ir() +** +** Computing ringing response: +** +** Sub_Ring() +** Upd_Ring() +** +** Synthesizing speech: +** +** Synt() +** Spf() +*/ + +#include + +#include "typedef.h" +#include "basop.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "coder.h" +#include "decod.h" +#include "util_lbc.h" +#include "lpc.h" +#include "cod_cng.h" + +/* +** +** Function: Comp_Lpc() +** +** Description: Computes the tenth-order LPC filters for an +** entire frame. For each subframe, a +** Hamming-windowed block of 180 samples, +** centered around the subframe, is used to +** compute eleven autocorrelation coefficients. +** The Levinson-Durbin algorithm then generates +** the LPC coefficients. This function requires +** a look-ahead of one subframe, and hence +** introduces a 7.5 ms encoding delay. +** +** Links to text: Section 2.4 +** +** Arguments: +** +** Word16 *UnqLpc Empty Buffer +** Word16 PrevDat[] Previous 2 subframes of samples (120 words) +** Word16 DataBuff[] Current frame of samples (240 words) +** +** Outputs: + +** +** Word16 UnqLpc[] LPC coefficients for entire frame (40 words) +** +** Return value: None +** +*/ +void +Comp_Lpc (CODSTATDEF * CodStat, Word16 * UnqLpc, Word16 * PrevDat, + Word16 * DataBuff) +{ + int i, j, k; + + Word16 Dpnt[Frame + LpcFrame - SubFrLen]; + Word16 Vect[LpcFrame]; + Word16 Acf_sf[LpcOrderP1 * SubFrames]; + Word16 ShAcf_sf[SubFrames]; + Word16 Exp; + Word16 *curAcf; + Word16 Pk2; + + Word32 Acc0, Acc1; + + /* + * Generate a buffer of 360 samples. This consists of 120 samples + * from the previous frame and 240 samples from the current frame. + */ + for (i = 0; i < LpcFrame - SubFrLen; i++) + Dpnt[i] = PrevDat[i]; + for (i = 0; i < Frame; i++) + Dpnt[i + LpcFrame - SubFrLen] = DataBuff[i]; + + + /* + * Repeat for all subframes + */ + curAcf = Acf_sf; + for (k = 0; k < SubFrames; k++) { + + + /* + * Do windowing + */ + + /* Get block of 180 samples centered around current subframe */ + for (i = 0; i < LpcFrame; i++) + Vect[i] = Dpnt[k * SubFrLen + i]; + + /* Normalize */ + ShAcf_sf[k] = Vec_Norm (Vect, (Word16) LpcFrame); + + /* Apply the Hamming window */ + for (i = 0; i < LpcFrame; i++) + Vect[i] = mult_r (Vect[i], HammingWindowTable[i]); + + + /* + * Compute the autocorrelation coefficients + */ + + /* Compute the zeroth-order coefficient (energy) */ + Acc1 = (Word32) 0; + for (i = 0; i < LpcFrame; i++) { + Acc0 = L_mult (Vect[i], Vect[i]); + Acc0 = L_shr (Acc0, (Word16) 1); + Acc1 = L_add (Acc1, Acc0); + } + + /* Apply a white noise correction factor of (1025/1024) */ + Acc0 = L_shr (Acc1, (Word16) RidgeFact); + Acc1 = L_add (Acc1, Acc0); + + /* Normalize the energy */ + Exp = norm_l (Acc1); + Acc1 = L_shl (Acc1, Exp); + + curAcf[0] = L_round (Acc1); + if (curAcf[0] == 0) { + for (i = 1; i <= LpcOrder; i++) + curAcf[i] = 0; + ShAcf_sf[k] = 40; + } + + else { + /* Compute the rest of the autocorrelation coefficients. + Multiply them by a binomial coefficients lag window. */ + for (i = 1; i <= LpcOrder; i++) { + Acc1 = (Word32) 0; + for (j = i; j < LpcFrame; j++) { + Acc0 = L_mult (Vect[j], Vect[j - i]); + Acc0 = L_shr (Acc0, (Word16) 1); + Acc1 = L_add (Acc1, Acc0); + } + Acc0 = L_shl (Acc1, Exp); + Acc0 = L_mls (Acc0, BinomialWindowTable[i - 1]); + curAcf[i] = L_round (Acc0); + } + /* Save Acf scaling factor */ + ShAcf_sf[k] = add (Exp, shl (ShAcf_sf[k], 1)); + } + + /* + * Apply the Levinson-Durbin algorithm to generate the LPC + * coefficients + */ + Durbin (&UnqLpc[k * LpcOrder], &curAcf[1], curAcf[0], &Pk2); + CodStat->SinDet <<= 1; + if (Pk2 > 0x799a) { + CodStat->SinDet++; + } + curAcf += LpcOrderP1; + } + + /* Update sine detector */ + CodStat->SinDet &= 0x7fff; + + j = CodStat->SinDet; + k = 0; + for (i = 0; i < 15; i++) { + k += j & 1; + j >>= 1; + } + if (k >= 14) + CodStat->SinDet |= 0x8000; + + /* Update CNG Acf memories */ + Update_Acf (CodStat, Acf_sf, ShAcf_sf); + +} + + +/* +** +** Function: Durbin() +** +** Description: Implements the Levinson-Durbin algorithm for a +** subframe. The Levinson-Durbin algorithm +** recursively computes the minimum mean-squared +** error (MMSE) linear prediction filter based on the +** estimated autocorrelation coefficients. +** +** Links to text: Section 2.4 +** +** Arguments: +** +** Word16 *Lpc Empty buffer +** Word16 Corr[] First- through tenth-order autocorrelations (10 words) +** Word16 Err Zeroth-order autocorrelation, or energy +** +** Outputs: +** +** Word16 Lpc[] LPC coefficients (10 words) +** +** Return value: The error +** +*/ +Word16 +Durbin (Word16 * Lpc, Word16 * Corr, Word16 Err, Word16 * Pk2) +{ + int i, j; + + Word16 Temp[LpcOrder]; + Word16 Pk; + + Word32 Acc0, Acc1, Acc2; + + /* + * Initialize the LPC vector + */ + for (i = 0; i < LpcOrder; i++) + Lpc[i] = (Word16) 0; + + /* + * Do the recursion. At the ith step, the algorithm computes the + * (i+1)th - order MMSE linear prediction filter. + */ + for (i = 0; i < LpcOrder; i++) { + +/* + * Compute the partial correlation (parcor) coefficient + */ + + /* Start parcor computation */ + Acc0 = L_deposit_h (Corr[i]); + Acc0 = L_shr (Acc0, (Word16) 2); + for (j = 0; j < i; j++) + Acc0 = L_msu (Acc0, Lpc[j], Corr[i - j - 1]); + Acc0 = L_shl (Acc0, (Word16) 2); + + /* Save sign */ + Acc1 = Acc0; + Acc0 = L_abs (Acc0); + + /* Finish parcor computation */ + Acc2 = L_deposit_h (Err); + if (Acc0 >= Acc2) { + *Pk2 = 32767; + break; + } + + Pk = div_l (Acc0, Err); + + if (Acc1 >= 0) + Pk = negate (Pk); + + /* + * Sine detector + */ + if (i == 1) + *Pk2 = Pk; + + /* + * Compute the ith LPC coefficient + */ + Acc0 = L_deposit_h (negate (Pk)); + Acc0 = L_shr (Acc0, (Word16) 2); + Lpc[i] = L_round (Acc0); + + /* + * Update the prediction error + */ + Acc1 = L_mls (Acc1, Pk); + Acc1 = L_add (Acc1, Acc2); + Err = L_round (Acc1); + + /* + * Compute the remaining LPC coefficients + */ + for (j = 0; j < i; j++) + Temp[j] = Lpc[j]; + + for (j = 0; j < i; j++) { + Acc0 = L_deposit_h (Lpc[j]); + Acc0 = L_mac (Acc0, Pk, Temp[i - j - 1]); + Lpc[j] = L_round (Acc0); + } + } + + return Err; +} + +/* +** +** Function: Wght_Lpc() +** +** Description: Computes the formant perceptual weighting +** filter coefficients for a frame. These +** coefficients are geometrically scaled versions +** of the unquantized LPC coefficients. +** +** Links to text: Section 2.8 +** +** Arguments: +** +** Word16 *PerLpc Empty Buffer +** Word16 UnqLpc[] Unquantized LPC coefficients (40 words) +** +** Outputs: + +** +** Word16 PerLpc[] Perceptual weighting filter coefficients +** (80 words) +** +** Return value: None +** +*/ +void +Wght_Lpc (Word16 * PerLpc, Word16 * UnqLpc) +{ + int i, j; + + + /* + * Do for all subframes + */ + for (i = 0; i < SubFrames; i++) { + + + /* + * Compute the jth FIR coefficient by multiplying the jth LPC + * coefficient by (0.9)^j. + */ + for (j = 0; j < LpcOrder; j++) + PerLpc[j] = mult_r (UnqLpc[j], PerFiltZeroTable[j]); + PerLpc += LpcOrder; + + +/* + * Compute the jth IIR coefficient by multiplying the jth LPC + * coefficient by (0.5)^j. + */ + for (j = 0; j < LpcOrder; j++) + PerLpc[j] = mult_r (UnqLpc[j], PerFiltPoleTable[j]); + PerLpc += LpcOrder; + UnqLpc += LpcOrder; + } +} + +/* +** +** Function: Error_Wght() +** +** Description: Implements the formant perceptual weighting +** filter for a frame. This filter effectively +** deemphasizes the formant frequencies in the +** error signal. +** +** Links to text: Section 2.8 +** +** Arguments: +** +** Word16 Dpnt[] Highpass filtered speech x[n] (240 words) +** Word16 PerLpc[] Filter coefficients (80 words) +** +** Inputs: +** +** CodStat->WghtFirDl[] FIR filter memory from previous frame (10 words) +** CodStat->WghtIirDl[] IIR filter memory from previous frame (10 words) + +** +** Outputs: +** +** Word16 Dpnt[] Weighted speech f[n] (240 words) +** +** Return value: None +** +*/ +void +Error_Wght (CODSTATDEF * CodStat, Word16 * Dpnt, Word16 * PerLpc) +{ + int i, j, k; + + Word32 Acc0; + + +/* + * Do for all subframes + */ + for (k = 0; k < SubFrames; k++) { + + for (i = 0; i < SubFrLen; i++) { + +/* + * Do the FIR part + */ + /* Filter */ + Acc0 = L_mult (*Dpnt, (Word16) 0x2000); + for (j = 0; j < LpcOrder; j++) + Acc0 = L_msu (Acc0, PerLpc[j], CodStat->WghtFirDl[j]); + + /* Update memory */ + for (j = LpcOrder - 1; j > 0; j--) + CodStat->WghtFirDl[j] = CodStat->WghtFirDl[j - 1]; + CodStat->WghtFirDl[0] = *Dpnt; + + /* + * Do the IIR part + */ + + /* Filter */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_mac (Acc0, PerLpc[LpcOrder + j], CodStat->WghtIirDl[j]); + for (j = LpcOrder - 1; j > 0; j--) + CodStat->WghtIirDl[j] = CodStat->WghtIirDl[j - 1]; + Acc0 = L_shl (Acc0, (Word16) 2); + + /* Update memory */ + CodStat->WghtIirDl[0] = L_round (Acc0); + *Dpnt++ = CodStat->WghtIirDl[0]; + } + PerLpc += 2 * LpcOrder; + } +} + +/* +** +** Function: Comp_Ir() +** +** Description: Computes the combined impulse response of the +** formant perceptual weighting filter, harmonic +** noise shaping filter, and synthesis filter for +** a subframe. +** +** Links to text: Section 2.12 +** +** Arguments: +** +** Word16 *ImpResp Empty Buffer +** Word16 QntLpc[] Quantized LPC coefficients (10 words) +** Word16 PerLpc[] Perceptual filter coefficients (20 words) +** PWDEF Pw Harmonic noise shaping filter parameters +** +** Outputs: +** +** Word16 ImpResp[] Combined impulse response (60 words) +** +** Return value: None +** +*/ +void +Comp_Ir (Word16 * ImpResp, Word16 * QntLpc, Word16 * PerLpc, PWDEF Pw) +{ + int i, j; + + Word16 FirDl[LpcOrder]; + Word16 IirDl[LpcOrder]; + Word16 Temp[PitchMax + SubFrLen]; + + Word32 Acc0, Acc1; + + + /* + * Clear all memory. Impulse response calculation requires + * an all-zero initial state. + */ + + /* Perceptual weighting filter */ + for (i = 0; i < LpcOrder; i++) + FirDl[i] = IirDl[i] = (Word16) 0; + + /* Harmonic noise shaping filter */ + for (i = 0; i < PitchMax + SubFrLen; i++) + Temp[i] = (Word16) 0; + + + /* + * Input a single impulse + */ + Acc0 = (Word32) 0x04000000L; + + /* + * Do for all elements in a subframe + */ + for (i = 0; i < SubFrLen; i++) { + + /* + * Synthesis filter + */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_mac (Acc0, QntLpc[j], FirDl[j]); + Acc1 = L_shl (Acc0, (Word16) 2); + + /* + * Perceptual weighting filter + */ + + /* FIR part */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_msu (Acc0, PerLpc[j], FirDl[j]); + Acc0 = L_shl (Acc0, (Word16) 1); + for (j = LpcOrder - 1; j > 0; j--) + FirDl[j] = FirDl[j - 1]; + FirDl[0] = L_round (Acc1); + + /* Iir part */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_mac (Acc0, PerLpc[LpcOrder + j], IirDl[j]); + for (j = LpcOrder - 1; j > 0; j--) + IirDl[j] = IirDl[j - 1]; + Acc0 = L_shl (Acc0, (Word16) 2); + IirDl[0] = L_round (Acc0); + Temp[PitchMax + i] = IirDl[0]; + + /* + * Harmonic noise shaping filter + */ + + Acc0 = L_deposit_h (IirDl[0]); + Acc0 = L_msu (Acc0, Pw.Gain, Temp[PitchMax - Pw.Indx + i]); + ImpResp[i] = L_round (Acc0); + + Acc0 = (Word32) 0; + } +} + +/* +** +** Function: Sub_Ring() +** +** Description: Computes the zero-input response of the +** combined formant perceptual weighting filter, +** harmonic noise shaping filter, and synthesis +** filter for a subframe. Subtracts the +** zero-input response from the harmonic noise +** weighted speech vector to produce the target +** speech vector. +** +** Links to text: Section 2.13 +** +** Arguments: +** +** Word16 Dpnt[] Harmonic noise weighted vector w[n] (60 words) +** Word16 QntLpc[] Quantized LPC coefficients (10 words) +** Word16 PerLpc[] Perceptual filter coefficients (20 words) +** Word16 PrevErr[] Harmonic noise shaping filter memory (145 words) +** PWDEF Pw Harmonic noise shaping filter parameters +** +** Inputs: +** +** CodStat->RingFirDl[] Perceptual weighting filter FIR memory from +** previous subframe (10 words) +** CodStat->RingIirDl[] Perceptual weighting filter IIR memory from +** previous subframe (10 words) +** +** Outputs: +** +** Word16 Dpnt[] Target vector t[n] (60 words) +** +** Return value: None +** +*/ +void +Sub_Ring (CODSTATDEF * CodStat, Word16 * Dpnt, Word16 * QntLpc, + Word16 * PerLpc, Word16 * PrevErr, PWDEF Pw) +{ + int i, j; + Word32 Acc0, Acc1; + + Word16 FirDl[LpcOrder]; + Word16 IirDl[LpcOrder]; + Word16 Temp[PitchMax + SubFrLen]; + + + /* + * Initialize the memory + */ + for (i = 0; i < PitchMax; i++) + Temp[i] = PrevErr[i]; + + for (i = 0; i < LpcOrder; i++) { + FirDl[i] = CodStat->RingFirDl[i]; + IirDl[i] = CodStat->RingIirDl[i]; + } + + /* + * Do for all elements in a subframe + */ + for (i = 0; i < SubFrLen; i++) { + + /* + * Input zero + */ + Acc0 = (Word32) 0; + + /* + * Synthesis filter + */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_mac (Acc0, QntLpc[j], FirDl[j]); + Acc1 = L_shl (Acc0, (Word16) 2); + + /* + * Perceptual weighting filter + */ + + /* Fir part */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_msu (Acc0, PerLpc[j], FirDl[j]); + for (j = LpcOrder - 1; j > 0; j--) + FirDl[j] = FirDl[j - 1]; + FirDl[0] = L_round (Acc1); + + /* Iir part */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_mac (Acc0, PerLpc[LpcOrder + j], IirDl[j]); + Acc0 = L_shl (Acc0, (Word16) 2); + for (j = LpcOrder - 1; j > 0; j--) + IirDl[j] = IirDl[j - 1]; + IirDl[0] = L_round (Acc0); + Temp[PitchMax + i] = IirDl[0]; + + /* + * Do the harmonic noise shaping filter and subtract the result + * from the harmonic noise weighted vector. + */ + Acc0 = L_deposit_h (sub (Dpnt[i], IirDl[0])); + Acc0 = L_mac (Acc0, Pw.Gain, Temp[PitchMax - (int) Pw.Indx + i]); + Dpnt[i] = L_round (Acc0); + } +} + +/* +** +** Function: Upd_Ring() +** +** Description: Updates the memory of the combined formant +** perceptual weighting filter, harmonic noise +** shaping filter, and synthesis filter for a +** subframe. The update is done by passing the +** current subframe's excitation through the +** combined filter. +** +** Links to text: Section 2.19 +** +** Arguments: +** +** Word16 Dpnt[] Decoded excitation for the current subframe e[n] +** (60 words) +** Word16 QntLpc[] Quantized LPC coefficients (10 words) +** Word16 PerLpc[] Perceptual filter coefficients (20 words) +** Word16 PrevErr[] Harmonic noise shaping filter memory (145 words) +** +** Inputs: +** +** CodStat->RingFirDl[] Perceptual weighting filter FIR memory from + +** previous subframe (10 words) +** CodStat->RingIirDl[] Perceptual weighting filter IIR memory from +** previous subframe (10 words) +** +** Outputs: +** +** Word16 PrevErr[] Updated harmonic noise shaping filter memory +** CodStat->RingFirDl[] Updated perceptual weighting filter FIR memory +** CodStat->RingIirDl[] Updated perceptual weighting filter IIR memory +** +** Return value: None +** +*/ +void +Upd_Ring (CODSTATDEF * CodStat, Word16 * Dpnt, Word16 * QntLpc, + Word16 * PerLpc, Word16 * PrevErr) +{ + int i, j; + + Word32 Acc0, Acc1; + + + /* + * Shift the harmonic noise shaping filter memory + */ + for (i = SubFrLen; i < PitchMax; i++) + PrevErr[i - SubFrLen] = PrevErr[i]; + + + /* + * Do for all elements in the subframe + */ + for (i = 0; i < SubFrLen; i++) { + + /* + * Input the current subframe's excitation + */ + Acc0 = L_deposit_h (Dpnt[i]); + Acc0 = L_shr (Acc0, (Word16) 3); + + /* + * Synthesis filter + */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_mac (Acc0, QntLpc[j], CodStat->RingFirDl[j]); + Acc1 = L_shl (Acc0, (Word16) 2); + + Dpnt[i] = shl (L_round (Acc1), (Word16) 1); + + /* + * Perceptual weighting filter + */ + + /* FIR part */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_msu (Acc0, PerLpc[j], CodStat->RingFirDl[j]); + + /* Update FIR memory */ + for (j = LpcOrder - 1; j > 0; j--) + CodStat->RingFirDl[j] = CodStat->RingFirDl[j - 1]; + CodStat->RingFirDl[0] = L_round (Acc1); + + /* IIR part */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_mac (Acc0, PerLpc[LpcOrder + j], CodStat->RingIirDl[j]); + Acc0 = L_shl (Acc0, (Word16) 2); + + /* Update IIR memory */ + for (j = LpcOrder - 1; j > 0; j--) + CodStat->RingIirDl[j] = CodStat->RingIirDl[j - 1]; + CodStat->RingIirDl[0] = L_round (Acc0); + + /* Update harmonic noise shaping memory */ + PrevErr[PitchMax - SubFrLen + i] = CodStat->RingIirDl[0]; + } +} + +/* +** +** Function: Synt() +** +** Description: Implements the decoder synthesis filter for a +** subframe. This is a tenth-order IIR filter. +** +** Links to text: Section 3.7 +** +** Arguments: +** +** Word16 Dpnt[] Pitch-postfiltered excitation for the current +** subframe ppf[n] (60 words) +** Word16 Lpc[] Quantized LPC coefficients (10 words) +** +** Inputs: +** +** DecStat->SyntIirDl[] Synthesis filter memory from previous subframe (10 words) +** +** Outputs: +** +** Word16 Dpnt[] Synthesized speech vector sy[n] +** DecStat->SyntIirDl[] Updated synthesis filter memory +** +** Return value: None +** +*/ +void +Synt (DECSTATDEF * DecStat, Word16 * Dpnt, Word16 * Lpc) +{ + int i, j; + + Word32 Acc0; + + + /* + * Do for all elements in the subframe + */ + for (i = 0; i < SubFrLen; i++) { + + /* + * Input the current subframe's excitation + */ + Acc0 = L_deposit_h (Dpnt[i]); + Acc0 = L_shr (Acc0, (Word16) 3); + + /* + * Synthesis + */ + + /* Filter */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_mac (Acc0, Lpc[j], DecStat->SyntIirDl[j]); + + /* Update memory */ + for (j = LpcOrder - 1; j > 0; j--) + DecStat->SyntIirDl[j] = DecStat->SyntIirDl[j - 1]; + + Acc0 = L_shl (Acc0, (Word16) 2); + + DecStat->SyntIirDl[0] = L_round (Acc0); + + /* + * Scale output if postfilter is off. (Otherwise output is + * scaled by the gain scaling unit.) + */ + if (DecStat->UsePf) + Dpnt[i] = DecStat->SyntIirDl[0]; + else + Dpnt[i] = shl (DecStat->SyntIirDl[0], (Word16) 1); + + } + +} + +/* +** +** Function: Spf() +** +** Description: Implements the formant postfilter for a +** subframe. The formant postfilter is a +** 10-pole, 10-zero ARMA filter followed by a +** single-tap tilt compensation filter. +** +** Links to text: Section 3.8 +** +** Arguments: +** +** Word16 Tv[] Synthesized speech vector sy[n] (60 words) +** Word16 Lpc[] Quantized LPC coefficients (10 words) +** +** Inputs: +** +** DecStat->PostIirDl[] Postfilter IIR memory from previous subframe (10 words) +** DecStat->PostFirDl[] Postfilter FIR memory from previous subframe (10 words) +** DecStat->Park Previous value of compensation filter parameter +** +** Outputs: +** +** Word16 Tv[] Postfiltered speech vector pf[n] (60 words) +** DecStat->PostIirDl[] Updated postfilter IIR memory +** DecStat->PostFirDl[] Updated postfilter FIR memory +** DecStat->Park Updated compensation filter parameter +** +** Return value: Input vector energy +** +*/ +Word32 +Spf (DECSTATDEF * DecStat, Word16 * Tv, Word16 * Lpc) +{ + int i, j; + + Word32 Acc0, Acc1; + Word32 Sen; + Word16 Tmp; + Word16 Exp; + + Word16 FirCoef[LpcOrder]; + Word16 IirCoef[LpcOrder]; + + Word16 TmpVect[SubFrLen]; + + /* + * Compute ARMA coefficients. Compute the jth FIR coefficient by + * multiplying the jth quantized LPC coefficient by (0.65)^j. + * Compute the jth IIR coefficient by multiplying the jth quantized + * LPC coefficient by (0.75)^j. This emphasizes the formants in + * the frequency response. + */ + for (i = 0; i < LpcOrder; i++) { + FirCoef[i] = mult_r (Lpc[i], PostFiltZeroTable[i]); + IirCoef[i] = mult_r (Lpc[i], PostFiltPoleTable[i]); + } + + /* + * Normalize the speech vector. + */ + for (i = 0; i < SubFrLen; i++) + TmpVect[i] = Tv[i]; + Exp = Vec_Norm (TmpVect, (Word16) SubFrLen); + + /* + * Compute the first two autocorrelation coefficients R[0] and R[1] + */ + Acc0 = (Word32) 0; + Acc1 = L_mult (TmpVect[0], TmpVect[0]); + for (i = 1; i < SubFrLen; i++) { + Acc0 = L_mac (Acc0, TmpVect[i], TmpVect[i - 1]); + Acc1 = L_mac (Acc1, TmpVect[i], TmpVect[i]); + } + + /* + * Scale the energy for the later use. + */ + Sen = L_shr (Acc1, (Word16) (2 * Exp + 4)); + + /* + * Compute the first-order partial correlation coefficient of the + * input speech vector. + */ + Tmp = extract_h (Acc1); + if (Tmp != (Word16) 0) { + + /* Compute first parkor */ + Acc0 = L_shr (Acc0, (Word16) 1); + Acc1 = Acc0; + Acc0 = L_abs (Acc0); + + Tmp = div_l (Acc0, Tmp); + + if (Acc1 < (Word32) 0) + Tmp = negate (Tmp); + } + else + Tmp = (Word16) 0; + + /* + * Compute the compensation filter parameter and update the memory + */ + Acc0 = L_deposit_h (DecStat->Park); + Acc0 = L_msu (Acc0, DecStat->Park, (Word16) 0x2000); + Acc0 = L_mac (Acc0, Tmp, (Word16) 0x2000); + DecStat->Park = L_round (Acc0); + + Tmp = mult (DecStat->Park, PreCoef); + Tmp &= (Word16) 0xfffc; + + + /* + * Do for all elements in the subframe + */ + for (i = 0; i < SubFrLen; i++) { + + /* + * Input the speech vector + */ + Acc0 = L_deposit_h (Tv[i]); + Acc0 = L_shr (Acc0, (Word16) 2); + + /* + * Formant postfilter + */ + + /* FIR part */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_msu (Acc0, FirCoef[j], DecStat->PostFirDl[j]); + + /* Update FIR memory */ + for (j = LpcOrder - 1; j > 0; j--) + DecStat->PostFirDl[j] = DecStat->PostFirDl[j - 1]; + DecStat->PostFirDl[0] = Tv[i]; + + /* IIR part */ + for (j = 0; j < LpcOrder; j++) + Acc0 = L_mac (Acc0, IirCoef[j], DecStat->PostIirDl[j]); + + /* Update IIR memory */ + for (j = LpcOrder - 1; j > 0; j--) + DecStat->PostIirDl[j] = DecStat->PostIirDl[j - 1]; + + Acc0 = L_shl (Acc0, (Word16) 2); + Acc1 = Acc0; + + DecStat->PostIirDl[0] = L_round (Acc0); + + /* + * Compensation filter + */ + Acc1 = L_mac (Acc1, DecStat->PostIirDl[1], Tmp); + + Tv[i] = L_round (Acc1); + } + return Sen; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/lpc.h asterisk-1.2.1/codecs/g723_1/lpc.h --- asterisk-1.2.1.ori/codecs/g723_1/lpc.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/lpc.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,26 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "lpc.h" +** +** Description: Function prototypes for "lpc.c" +** +*/ + +#include "coder.h" +#include "decod.h" + +void Comp_Lpc (CODSTATDEF * CodStat, Word16 * UnqLpc, Word16 * PrevDat, + Word16 * DataBuff); +Word16 Durbin (Word16 * Lpc, Word16 * Corr, Word16 Err, Word16 * Pk2); +void Wght_Lpc (Word16 * PerLpc, Word16 * UnqLpc); +void Error_Wght (CODSTATDEF * CodStat, Word16 * Dpnt, Word16 * PerLpc); +void Comp_Ir (Word16 * ImpResp, Word16 * QntLpc, Word16 * PerLpc, PWDEF Pw); +void Sub_Ring (CODSTATDEF * CodStat, Word16 * Dpnt, Word16 * QntLpc, + Word16 * PerLpc, Word16 * PrevErr, PWDEF Pw); +void Upd_Ring (CODSTATDEF * CodStat, Word16 * Dpnt, Word16 * QntLpc, + Word16 * PerLpc, Word16 * PrevErr); +void Synt (DECSTATDEF * DecStat, Word16 * Dpnt, Word16 * Lpc); +Word32 Spf (DECSTATDEF * DecStat, Word16 * Tv, Word16 * Lpc); diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/lsp.c asterisk-1.2.1/codecs/g723_1/lsp.c --- asterisk-1.2.1.ori/codecs/g723_1/lsp.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/lsp.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,895 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: lsp.c +** +** Description: Functions that implement line spectral pair +** (LSP) operations. +** +** Functions: +** +** Converting between linear predictive coding (LPC) coefficients +** and LSP frequencies: +** +** AtoLsp() +** LsptoA() +** +** Vector quantization (VQ) of LSP frequencies: +** +** Lsp_Qnt() +** Lsp_Svq() +** Lsp_Inq() +** +** Interpolation of LSP frequencies: +** +** Lsp_Int() +*/ + + +#include + +#include "typedef.h" +#include "basop.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "lsp.h" + + +/* +** +** Function: AtoLsp() +** +** Description: Transforms 10 LPC coefficients to the 10 +** corresponding LSP frequencies for a subframe. +** This transformation is done once per frame, +** for subframe 3 only. The transform algorithm +** generates sum and difference polynomials from +** the LPC coefficients. It then evaluates the +** sum and difference polynomials at uniform +** intervals of pi/256 along the unit circle. +** Intervals where a sign change occurs are +** interpolated to find the zeros of the +** polynomials, which are the LSP frequencies. +** +** Links to text: Section 2.5 +** +** Arguments: +** +** Word16 *LspVect Empty Buffer +** Word16 Lpc[] Unquantized LPC coefficients (10 words) +** Word16 PrevLsp[] LSP frequencies from the previous frame (10 words) +** +** Outputs: +** +** Word16 LspVect[] LSP frequencies for the current frame (10 words) +** +** Return value: None +** +**/ +void +AtoLsp (Word16 * LspVect, Word16 * Lpc, Word16 * PrevLsp) +{ + + int i, j, k; + + Word32 Lpq[LpcOrder + 2]; + Word16 Spq[LpcOrder + 2]; + + Word16 Exp; + Word16 LspCnt; + + Word32 PrevVal, CurrVal; + Word32 Acc0, Acc1; + + + /* + * Perform a bandwidth expansion on the LPC coefficients. This + * scales the poles of the LPC synthesis filter by a factor of + * 0.994. + */ + for (i = 0; i < LpcOrder; i++) + LspVect[i] = mult_r (Lpc[i], BandExpTable[i]); + + + /* + * Compute the sum and difference polynomials with the roots at z = + * -1 (sum) or z = +1 (difference) removed. Let these polynomials + * be P(z) and Q(z) respectively, and let their coefficients be + * {p_i} amd {q_i}. The coefficients are stored in the array Lpq[] + * as follows: p_0, q_0, p_1, q_1, ..., p_5, q_5. There is no need + * to store the other coefficients because of symmetry. + */ + + + /* + * Set p_0 = q_0 = 1. The LPC coefficients are already scaled by + * 1/4. P(z) and Q(z) are scaled by an additional scaling factor of + * 1/16, for an overall factor of 1/64 = 0x02000000L. + */ + + Lpq[0] = Lpq[1] = (Word32) 0x02000000L; + + /* + * This loop computes the coefficients of P(z) and Q(z). The long + * division (to remove the real zeros) is done recursively. + */ + for (i = 0; i < LpcOrder / 2; i++) { + + /* P(z) */ + Acc0 = L_negate (Lpq[2 * i + 0]); + Acc1 = L_deposit_h (LspVect[i]); + Acc1 = L_shr (Acc1, (Word16) 4); + Acc0 = L_sub (Acc0, Acc1); + Acc1 = L_deposit_h (LspVect[LpcOrder - 1 - i]); + Acc1 = L_shr (Acc1, (Word16) 4); + Acc0 = L_sub (Acc0, Acc1); + Lpq[2 * i + 2] = Acc0; + + /* Q(z) */ + Acc0 = Lpq[2 * i + 1]; + Acc1 = L_deposit_h (LspVect[i]); + Acc1 = L_shr (Acc1, (Word16) 4); + + Acc0 = L_sub (Acc0, Acc1); + Acc1 = L_deposit_h (LspVect[LpcOrder - 1 - i]); + Acc1 = L_shr (Acc1, (Word16) 4); + Acc0 = L_add (Acc0, Acc1); + Lpq[2 * i + 3] = Acc0; + } + + /* + * Divide p_5 and q_5 by 2 for proper weighting during polynomial + * evaluation. + */ + Lpq[LpcOrder + 0] = L_shr (Lpq[LpcOrder + 0], (Word16) 1); + Lpq[LpcOrder + 1] = L_shr (Lpq[LpcOrder + 1], (Word16) 1); + + /* + * Normalize the polynomial coefficients and convert to shorts + */ + + /* Find the maximum */ + Acc1 = L_abs (Lpq[0]); + for (i = 1; i < LpcOrder + 2; i++) { + Acc0 = L_abs (Lpq[i]); + if (Acc0 > Acc1) + Acc1 = Acc0; + } + + /* Compute the normalization factor */ + Exp = norm_l (Acc1); + + + /* Normalize and convert to shorts */ + for (i = 0; i < LpcOrder + 2; i++) { + Acc0 = L_shl (Lpq[i], Exp); + Spq[i] = L_round (Acc0); + } + + /* + * Initialize the search loop + */ + + /* + * The variable k is a flag that indicates which polynomial (sum or + * difference) the algorithm is currently evaluating. Start with + * the sum. + */ + k = 0; + + /* Evaluate the sum polynomial at frequency zero */ + PrevVal = (Word32) 0; + for (j = 0; j <= LpcOrder / 2; j++) + PrevVal = L_mac (PrevVal, Spq[2 * j], CosineTable[0]); + + + /* + * Search loop. Evaluate P(z) and Q(z) at uniform intervals of + * pi/256 along the unit circle. Check for zero crossings. The + * zeros of P(w) and Q(w) alternate, so only one of them need by + * evaluated at any given step. + */ + LspCnt = (Word16) 0; + for (i = 1; i < CosineTableSize / 2; i++) { + + /* Evaluate the selected polynomial */ + CurrVal = (Word32) 0; + for (j = 0; j <= LpcOrder / 2; j++) + CurrVal = L_mac (CurrVal, Spq[LpcOrder - 2 * j + k], + CosineTable[i * j % CosineTableSize]); + + /* Check for a sign change, indicating a zero crossing */ + if ((CurrVal ^ PrevVal) < (Word32) 0) { + + /* + * Interpolate to find the bottom 7 bits of the + * zero-crossing frequency + */ + Acc0 = L_abs (CurrVal); + Acc1 = L_abs (PrevVal); + Acc0 = L_add (Acc0, Acc1); + + /* Normalize the sum */ + Exp = norm_l (Acc0); + Acc0 = L_shl (Acc0, Exp); + Acc1 = L_shl (Acc1, Exp); + + Acc1 = L_shr (Acc1, (Word16) 8); + + LspVect[LspCnt] = div_l (Acc1, extract_h (Acc0)); + + /* + * Add the upper part of the zero-crossing frequency, + * i.e. bits 7-15 + */ + Exp = shl ((Word16) (i - 1), (Word16) 7); + LspVect[LspCnt] = add (LspVect[LspCnt], Exp); + LspCnt++; + + /* Check if all zeros have been found */ + if (LspCnt == (Word16) LpcOrder) + break; + + /* + * Switch the pointer between sum and difference polynomials + */ + k ^= 1; + + /* + * Evaluate the new polynomial at the current frequency + */ + CurrVal = (Word32) 0; + for (j = 0; j <= LpcOrder / 2; j++) + CurrVal = L_mac (CurrVal, Spq[LpcOrder - 2 * j + k], + CosineTable[i * j % CosineTableSize]); + } + + /* Update the previous value */ + PrevVal = CurrVal; + } + + + /* + * Check if all 10 zeros were found. If not, ignore the results of + * the search and use the previous frame's LSP frequencies instead. + */ + if (LspCnt != (Word16) LpcOrder) { + for (j = 0; j < LpcOrder; j++) + LspVect[j] = PrevLsp[j]; + } + + return; +} + +/* +** +** Function: Lsp_Qnt() +** +** Description: Vector quantizes the LSP frequencies. The LSP +** vector is divided into 3 sub-vectors, or +** bands, of dimension 3, 3, and 4. Each band is +** quantized separately using a different VQ +** table. Each table has 256 entries, so the +** quantization generates three indices of 8 bits +** each. (Only the LSP vector for subframe 3 is +** quantized per frame.) +** +** Links to text: Section 2.5 +** +** Arguments: +** +** Word16 CurrLsp[] Unquantized LSP frequencies for the current frame (10 words) +** Word16 PrevLsp[] LSP frequencies from the previous frame (10 words) +** +** Outputs: Quantized LSP frequencies for the current frame (10 words) +** +** Return value: +** +** Word32 Long word packed with the 3 VQ indices. Band 0 +** corresponds to bits [23:16], band 1 corresponds +** to bits [15:8], and band 2 corresponds to bits [7:0]. +** (Bit 0 is the least significant.) +** +*/ +Word32 +Lsp_Qnt (Word16 * CurrLsp, Word16 * PrevLsp) +{ + int i; + + Word16 Wvect[LpcOrder]; + + Word16 Tmp0, Tmp1; + Word16 Exp; + + + /* + * Compute the VQ weighting vector. The weights assign greater + * precision to those frequencies that are closer together. + */ + + /* Compute the end differences */ + Wvect[0] = sub (CurrLsp[1], CurrLsp[0]); + Wvect[LpcOrder - 1] = sub (CurrLsp[LpcOrder - 1], CurrLsp[LpcOrder - 2]); + + /* Compute the rest of the differences */ + for (i = 1; i < LpcOrder - 1; i++) { + Tmp0 = sub (CurrLsp[i + 1], CurrLsp[i]); + Tmp1 = sub (CurrLsp[i], CurrLsp[i - 1]); + if (Tmp0 > Tmp1) + Wvect[i] = Tmp1; + else + Wvect[i] = Tmp0; + } + + /* Invert the differences */ + Tmp0 = (Word16) 0x0020; + for (i = 0; i < LpcOrder; i++) { + + if (Wvect[i] > Tmp0) + Wvect[i] = div_s (Tmp0, Wvect[i]); + else + Wvect[i] = MAX_16; + } + + /* Normalize the weight vector */ + Tmp0 = (Word16) 0; + for (i = 0; i < LpcOrder; i++) + if (Wvect[i] > Tmp0) + Tmp0 = Wvect[i]; + + Exp = norm_s (Tmp0); + for (i = 0; i < LpcOrder; i++) + Wvect[i] = shl (Wvect[i], Exp); + + + /* + * Compute the VQ target vector. This is the residual that remains + * after subtracting both the DC and predicted + * components. + */ + + /* + * Subtract the DC component from both the current and previous LSP + * vectors. + */ + for (i = 0; i < LpcOrder; i++) { + CurrLsp[i] = sub (CurrLsp[i], LspDcTable[i]); + PrevLsp[i] = sub (PrevLsp[i], LspDcTable[i]); + } + + /* + * Generate the prediction vector and subtract it. Use a constant + * first-order predictor based on the previous (DC-free) LSP + * vector. + */ + for (i = 0; i < LpcOrder; i++) { + Tmp0 = mult_r (PrevLsp[i], (Word16) LspPrd0); + CurrLsp[i] = sub (CurrLsp[i], Tmp0); + } + + /* + * Add the DC component back to the previous LSP vector. This + * vector is needed in later routines. + */ + for (i = 0; i < LpcOrder; i++) + PrevLsp[i] = add (PrevLsp[i], LspDcTable[i]); + + /* + * Do the vector quantization for all three bands + */ + return Lsp_Svq (CurrLsp, Wvect); +} + +/* +** +** Function: Lsp_Svq() +** +** Description: Performs the search of the VQ tables to find +** the optimum LSP indices for all three bands. +** For each band, the search finds the index which +** minimizes the weighted squared error between +** the table entry and the target. +** +** Links to text: Section 2.5 +** +** Arguments: +** +** Word16 Tv[] VQ target vector (10 words) +** Word16 Wvect[] VQ weight vector (10 words) +** +** Outputs: None +** +** Return value: +** +** Word32 Long word packed with the 3 VQ indices. Band 0 +** corresponds to bits [23:16], band 1 corresponds +** to bits [15:8], and band 2 corresponds to bits [7:0]. +** +*/ +Word32 +Lsp_Svq (Word16 * Tv, Word16 * Wvect) +{ + int i, j, k; + + Word32 Rez, Indx; + Word32 Acc0, Acc1; + + Word16 Tmp[LpcOrder]; + Word16 *LspQntPnt; + + + /* + * Initialize the return value + */ + Rez = (Word32) 0; + + /* + * Quantize each band separately + */ + for (k = 0; k < LspQntBands; k++) { + + /* + * Search over the entire VQ table to find the index that + * minimizes the error. + */ + + /* Initialize the search */ + Acc1 = (Word32) - 1; + Indx = (Word32) 0; + LspQntPnt = BandQntTable[k]; + + for (i = 0; i < LspCbSize; i++) { + + /* + * Generate the metric, which is the negative error with the + * constant component removed. + */ + for (j = 0; j < BandInfoTable[k][1]; j++) + Tmp[j] = mult_r (Wvect[BandInfoTable[k][0] + j], LspQntPnt[j]); + + Acc0 = (Word32) 0; + for (j = 0; j < BandInfoTable[k][1]; j++) + Acc0 = L_mac (Acc0, Tv[BandInfoTable[k][0] + j], Tmp[j]); + Acc0 = L_shl (Acc0, (Word16) 1); + for (j = 0; j < BandInfoTable[k][1]; j++) + Acc0 = L_msu (Acc0, LspQntPnt[j], Tmp[j]); + + LspQntPnt += BandInfoTable[k][1]; + + /* + * Compare the metric to the previous maximum and select the + * new index + */ + if (Acc0 > Acc1) { + Acc1 = Acc0; + Indx = (Word32) i; + } + } + + /* + * Pack the result with the optimum index for this band + */ + Rez = L_shl (Rez, (Word16) LspCbBits); + Rez = L_add (Rez, Indx); + } + + return Rez; +} + +/* +** +** Function: Lsp_Inq() +** +** Description: Performs inverse vector quantization of the +** LSP frequencies. The LSP vector is divided +** into 3 sub-vectors, or bands, of dimension 3, +** 3, and 4. Each band is inverse quantized +** separately using a different VQ table. Each +** table has 256 entries, so each VQ index is 8 +** bits. (Only the LSP vector for subframe 3 is +** quantized per frame.) +** +** Links to text: Sections 2.6, 3.2 +** +** Arguments: +** +** Word16 *Lsp Empty buffer +** Word16 PrevLsp[] Quantized LSP frequencies from the previous frame +** (10 words) +** Word32 LspId Long word packed with the 3 VQ indices. Band 0 +** corresponds to bits [23:16], band 1 corresponds +** to bits [15:8], and band 2 corresponds to bits +** [7:0]. +** Word16 Crc Frame erasure indicator +** +** Outputs: +** +** Word16 Lsp[] Quantized LSP frequencies for current frame (10 +** words) +** +** Return value: None +** +*/ +void +Lsp_Inq (Word16 * Lsp, Word16 * PrevLsp, Word32 LspId, Word16 Crc) +{ + int i, j; + + Word16 *LspQntPnt; + + + Word16 Scon; + Word16 Lprd; + + Word16 Tmp; + Flag Test; + + + /* + * Check for frame erasure. If a frame erasure has occurred, the + * resulting VQ table entries are zero. In addition, a different + * fixed predictor and minimum frequency separation are used. + */ + if (Crc == (Word16) 0) { + Scon = (Word16) 0x0100; + Lprd = LspPrd0; + } + else { + LspId = (Word32) 0; + Scon = (Word16) 0x0200; + Lprd = LspPrd1; + } + + + /* + * Inverse quantize the 10th-order LSP vector. Each band is done + * separately. + */ + for (i = LspQntBands - 1; i >= 0; i--) { + + /* + * Get the VQ table entry corresponding to the transmitted index + */ + Tmp = (Word16) (LspId & (Word32) 0x000000ff); + LspId >>= 8; + + LspQntPnt = BandQntTable[i]; + + for (j = 0; j < BandInfoTable[i][1]; j++) + Lsp[BandInfoTable[i][0] + j] = LspQntPnt[Tmp * BandInfoTable[i][1] + j]; + } + + /* + * Subtract the DC component from the previous frame's quantized + * vector + */ + for (j = 0; j < LpcOrder; j++) + PrevLsp[j] = sub (PrevLsp[j], LspDcTable[j]); + + /* + * Generate the prediction vector using a fixed first-order + * predictor based on the previous frame's (DC-free) quantized + * vector + */ + for (j = 0; j < LpcOrder; j++) { + Tmp = mult_r (PrevLsp[j], Lprd); + Lsp[j] = add (Lsp[j], Tmp); + } + + /* + * Add the DC component back to the previous quantized vector, + * which is needed in later routines + */ + for (j = 0; j < LpcOrder; j++) { + PrevLsp[j] = add (PrevLsp[j], LspDcTable[j]); + Lsp[j] = add (Lsp[j], LspDcTable[j]); + } + + + /* + * Perform a stability test on the quantized LSP frequencies. This + * test checks that the frequencies are ordered, with a minimum + * separation between each. If the test fails, the frequencies are + * iteratively modified until the test passes. If after 10 + * iterations the test has not passed, the previous frame's + * quantized LSP vector is used. + */ + for (i = 0; i < LpcOrder; i++) { + + /* Check the first frequency */ + if (Lsp[0] < (Word16) 0x180) + Lsp[0] = (Word16) 0x180; + + /* Check the last frequency */ + if (Lsp[LpcOrder - 1] > (Word16) 0x7e00) + Lsp[LpcOrder - 1] = (Word16) 0x7e00; + + /* Perform the modification */ + for (j = 1; j < LpcOrder; j++) { + + Tmp = add (Scon, Lsp[j - 1]); + Tmp = sub (Tmp, Lsp[j]); + if (Tmp > (Word16) 0) { + Tmp = shr (Tmp, (Word16) 1); + Lsp[j - 1] = sub (Lsp[j - 1], Tmp); + Lsp[j] = add (Lsp[j], Tmp); + } + } + + Test = False; + + /* + * Test the modified frequencies for stability. Break out of + * the loop if the frequencies are stable. + */ + for (j = 1; j < LpcOrder; j++) { + Tmp = add (Lsp[j - 1], Scon); + Tmp = sub (Tmp, (Word16) 4); + Tmp = sub (Tmp, Lsp[j]); + if (Tmp > (Word16) 0) + Test = True; + } + + if (Test == False) + break; + } + + + /* + * Return the result of the stability check. True = not stable, + * False = stable. + */ + if (Test == True) { + for (j = 0; j < LpcOrder; j++) + Lsp[j] = PrevLsp[j]; + } + + return; +} + +/* +** +** Function: Lsp_Int() +** +** Description: Computes the quantized LPC coefficients for a +** frame. First the quantized LSP frequencies +** for all subframes are computed by linear +** interpolation. These frequencies are then +** transformed to quantized LPC coefficients. +** +** Links to text: Sections 2.7, 3.3 +** +** Arguments: +** +** Word16 *QntLpc Empty buffer +** Word16 CurrLsp[] Quantized LSP frequencies for the current frame, +** subframe 3 (10 words) +** Word16 PrevLsp[] Quantized LSP frequencies for the previous frame, +** subframe 3 (10 words) +** +** Outputs: +** +** Word16 QntLpc[] Quantized LPC coefficients for current frame, all +** subframes (40 words) +** +** Return value: None +** +*/ +void +Lsp_Int (Word16 * QntLpc, Word16 * CurrLsp, Word16 * PrevLsp) +{ + int i, j; + + Word16 Tmp; + Word16 *Dpnt; + + Word32 Acc0; + + + /* + * Initialize the interpolation factor + */ + Tmp = (Word16) (MIN_16 / SubFrames); + + Dpnt = QntLpc; + + + /* + * Do for all subframes + */ + for (i = 0; i < SubFrames; i++) { + + /* + * Compute the quantized LSP frequencies by linear interpolation + * of the frequencies from subframe 3 of the current and + * previous frames + */ + for (j = 0; j < LpcOrder; j++) { + Acc0 = L_deposit_h (PrevLsp[j]); + Acc0 = L_mac (Acc0, Tmp, PrevLsp[j]); + Acc0 = L_msu (Acc0, Tmp, CurrLsp[j]); + Dpnt[j] = L_round (Acc0); + } + + /* + * Convert the quantized LSP frequencies to quantized LPC + * coefficients + */ + LsptoA (Dpnt); + Dpnt += LpcOrder; + + /* Update the interpolation factor */ + Tmp = add (Tmp, (Word16) (MIN_16 / SubFrames)); + } + +} + + +/* +** +** Function: LsptoA() +** +** Description: Converts LSP frequencies to LPC coefficients +** for a subframe. Sum and difference +** polynomials are computed from the LSP +** frequencies (which are the roots of these +** polynomials). The LPC coefficients are then +** computed by adding the sum and difference +** polynomials. +** +** Links to text: Sections 2.7, 3.3 +** +** Arguments: +** +** Word16 Lsp[] LSP frequencies (10 words) +** +** Outputs: +** +** Word16 Lsp[] LPC coefficients (10 words) +** +** Return value: None +** +*/ +void +LsptoA (Word16 * Lsp) +{ + int i, j; + + Word32 Acc0, Acc1; + Word16 Tmp; + + Word32 P[LpcOrder / 2 + 1]; + Word32 Q[LpcOrder / 2 + 1]; + + + /* + * Compute the cosines of the LSP frequencies by table lookup and + * linear interpolation + */ + for (i = 0; i < LpcOrder; i++) { + + /* + * Do the table lookup using bits [15:7] of the LSP frequency + */ + j = (int) shr (Lsp[i], (Word16) 7); + Acc0 = L_deposit_h (CosineTable[j]); + + /* + * Do the linear interpolations using bits [6:0] of the LSP + * frequency + */ + Tmp = sub (CosineTable[j + 1], CosineTable[j]); + Acc0 = L_mac (Acc0, Tmp, add (shl ((Word16) (Lsp[i] & 0x007f), + (Word16) 8), (Word16) 0x0080)); + Acc0 = L_shl (Acc0, (Word16) 1); + Lsp[i] = negate (L_round (Acc0)); + } + + + /* + * Compute the sum and difference polynomials with the real roots + * removed. These are computed by polynomial multiplication as + * follows. Let the sum polynomial be P(z). Define the elementary + * polynomials P_i(z) = 1 - 2cos(w_i) z^{-1} + z^{-2}, for 1<=i<= + * 5, where {w_i} are the LSP frequencies corresponding to the sum + * polynomial. Then P(z) = P_1(z)P_2(z)...P_5(z). Similarly + * the difference polynomial Q(z) = Q_1(z)Q_2(z)...Q_5(z). + */ + + /* + * Initialize the arrays with the coefficients of the product + * P_1(z)P_2(z) and Q_1(z)Q_2(z). Scale by 1/8. + */ + P[0] = (Word32) 0x10000000L; + P[1] = L_mult (Lsp[0], (Word16) 0x2000); + P[1] = L_mac (P[1], Lsp[2], (Word16) 0x2000); + P[2] = L_mult (Lsp[0], Lsp[2]); + P[2] = L_shr (P[2], (Word16) 1); + P[2] = L_add (P[2], (Word32) 0x20000000L); + + Q[0] = (Word32) 0x10000000L; + Q[1] = L_mult (Lsp[1], (Word16) 0x2000); + Q[1] = L_mac (Q[1], Lsp[3], (Word16) 0x2000); + Q[2] = L_mult (Lsp[1], Lsp[3]); + Q[2] = L_shr (Q[2], (Word16) 1); + Q[2] = L_add (Q[2], (Word32) 0x20000000L); + + /* + * Compute the intermediate polynomials P_1(z)P_2(z)...P_i(z) and + * Q_1(z)Q_2(z)...Q_i(z), for i = 2, 3, 4. Each intermediate + * polynomial is symmetric, so only the coefficients up to i+1 need + * by computed. Scale by 1/2 each iteration for a total of 1/8. + */ + for (i = 2; i < LpcOrder / 2; i++) { + + /* Compute coefficient (i+1) */ + Acc0 = P[i]; + Acc0 = L_mls (Acc0, Lsp[2 * i + 0]); + Acc0 = L_add (Acc0, P[i - 1]); + P[i + 1] = Acc0; + + Acc1 = Q[i]; + Acc1 = L_mls (Acc1, Lsp[2 * i + 1]); + Acc1 = L_add (Acc1, Q[i - 1]); + Q[i + 1] = Acc1; + + /* Compute coefficients i, i-1, ..., 2 */ + for (j = i; j >= 2; j--) { + Acc0 = P[j - 1]; + Acc0 = L_mls (Acc0, Lsp[2 * i + 0]); + Acc0 = L_add (Acc0, L_shr (P[j], (Word16) 1)); + Acc0 = L_add (Acc0, L_shr (P[j - 2], (Word16) 1)); + P[j] = Acc0; + + Acc1 = Q[j - 1]; + Acc1 = L_mls (Acc1, Lsp[2 * i + 1]); + Acc1 = L_add (Acc1, L_shr (Q[j], (Word16) 1)); + Acc1 = L_add (Acc1, L_shr (Q[j - 2], (Word16) 1)); + Q[j] = Acc1; + } + + /* Compute coefficients 1, 0 */ + P[0] = L_shr (P[0], (Word16) 1); + Q[0] = L_shr (Q[0], (Word16) 1); + + Acc0 = L_deposit_h (Lsp[2 * i + 0]); + Acc0 = L_shr (Acc0, (Word16) i); + Acc0 = L_add (Acc0, P[1]); + Acc0 = L_shr (Acc0, (Word16) 1); + P[1] = Acc0; + + Acc1 = L_deposit_h (Lsp[2 * i + 1]); + Acc1 = L_shr (Acc1, (Word16) i); + Acc1 = L_add (Acc1, Q[1]); + Acc1 = L_shr (Acc1, (Word16) 1); + Q[1] = Acc1; + } + + + /* + * Convert the sum and difference polynomials to LPC coefficients + * The LPC polynomial is the sum of the sum and difference + * polynomials with the real zeros factored in: A(z) = 1/2 {P(z) (1 + * + z^{-1}) + Q(z) (1 - z^{-1})}. The LPC coefficients are scaled + * here by 16; the overall scale factor for the LPC coefficients + * returned by this function is therefore 1/4. + */ + for (i = 0; i < LpcOrder / 2; i++) { + Acc0 = P[i]; + Acc0 = L_add (Acc0, P[i + 1]); + Acc0 = L_sub (Acc0, Q[i]); + Acc0 = L_add (Acc0, Q[i + 1]); + Acc0 = L_shl (Acc0, (Word16) 3); + Lsp[i] = negate (L_round (Acc0)); + + Acc1 = P[i]; + Acc1 = L_add (Acc1, P[i + 1]); + Acc1 = L_add (Acc1, Q[i]); + Acc1 = L_sub (Acc1, Q[i + 1]); + Acc1 = L_shl (Acc1, (Word16) 3); + Lsp[LpcOrder - 1 - i] = negate (L_round (Acc1)); + } + +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/lsp.h asterisk-1.2.1/codecs/g723_1/lsp.h --- asterisk-1.2.1.ori/codecs/g723_1/lsp.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/lsp.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,17 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "lsp.h" +** +** Description: Function prototypes for "lpc.c" +** +*/ + +void AtoLsp (Word16 * LspVect, Word16 * Lpc, Word16 * PrevLsp); +Word32 Lsp_Qnt (Word16 * CurrLsp, Word16 * PrevLsp); +Word32 Lsp_Svq (Word16 * Tv, Word16 * Wvect); +void Lsp_Inq (Word16 * Lsp, Word16 * PrevLsp, Word32 LspId, Word16 Crc); +void Lsp_Int (Word16 * QntLpc, Word16 * CurrLsp, Word16 * PrevLsp); +void LsptoA (Word16 * Lsp); diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/tab_lbc.c asterisk-1.2.1/codecs/g723_1/tab_lbc.c --- asterisk-1.2.1.ori/codecs/g723_1/tab_lbc.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/tab_lbc.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,2992 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +*/ + + +#include "typedef.h" +#include "cst_lbc.h" +#include "tab_lbc.h" + +/* +** +** File: tab_lbc.c +** +** Description: Tables used for G.723 encoding and decoding +** +** Tables: HammingWindowTable[180] +** +** LPC Computation and Filtering +** +** BinomialWindowTable[10] +** BandExpTable[10] +** +** LSP calculation and quantization +** +** CosineTable[512] +** LspDcTable[10] +** BandInfoTable[3][2] +** Band0Tb8[256*3] +** Band1Tb8[256*3] +** Band2Tb8[256*4] +** BandQntTable[3] +** +** Perceptual Filtering and Post Filtering +** + +** PerFiltZeroTable[10] +** PerFiltPoleTable[10] +** PostFiltZeroTable[10] +** PostFiltPoleTable[10] +** LpfConstTable[2] (pitch postfilter) +** +** ACELP or MP-MLQ +** +** Nb_puls[4] (MP-MLQ) +** FcbkGainTable[24] (ACELP and MP-MLQ) +** MaxPosTable[4] (MP-MLQ), Word32 +** CombinatorialTable[6][30](MP-MLQ),Word32 +** epsi170[170] (ACELP) +** gain170[170] (ACELP) +** +** Pitch Prediction +** +** AcbkGainTable085[85*20] +** AcbkGainTable170[170*20] +** AcbkGainTablePtr[2] +** +** Taming procedure +** +** tabgain170[170] +** tabgain85[85] +** +** Comfort Noise Generation +** +** fact[4] +** L_bseg[3], Word32 +** base[3] +** +** +** All tables are Word16 unless separately denoted +*/ + +/* +** HammingWindowTable: +** +** Hamming Window coefficients scaled by 32768 (Q15). +** +*/ + +Word16 HammingWindowTable[LpcFrame] = { + 2621, + 2631, + 2659, + 2705, + 2770, + 2853, + 2955, + 3074, + 3212, + 3367, + 3541, + 3731, + 3939, + 4164, + 4405, + 4663, + 4937, + 5226, + 5531, + 5851, + 6186, + 6534, + 6897, + 7273, + 7661, + 8062, + 8475, + 8899, + 9334, + 9780, + 10235, + 10699, + 11172, + 11653, + 12141, + 12636, + 13138, + 13645, + 14157, + 14673, + 15193, + 15716, + 16242, + 16769, + 17298, + 17827, + 18356, + 18884, + 19411, + 19935, + 20457, + 20975, + 21489, + 21999, + 22503, + 23002, + 23494, + 23978, + 24455, + 24924, + 25384, + 25834, + 26274, + 26704, + 27122, + 27529, + 27924, + 28306, + 28675, + 29031, + 29373, + 29700, + 30012, + 30310, + 30592, + 30857, + 31107, + 31340, + 31557, + 31756, + 31938, + 32102, + 32249, + 32377, + 32488, + 32580, + 32654, + 32710, + 32747, + 32766, + 32766, + 32747, + 32710, + 32654, + 32580, + 32488, + 32377, + 32249, + 32102, + 31938, + 31756, + 31557, + 31340, + 31107, + 30857, + 30592, + 30310, + 30012, + 29700, + 29373, + 29031, + 28675, + 28306, + 27924, + 27529, + 27122, + 26704, + 26274, + 25834, + 25384, + 24924, + 24455, + 23978, + 23494, + 23002, + 22503, + 21999, + 21489, + 20975, + 20457, + 19935, + 19411, + 18884, + 18356, + 17827, + 17298, + 16769, + 16242, + 15716, + 15193, + 14673, + 14157, + 13645, + 13138, + 12636, + 12141, + 11653, + 11172, + 10699, + 10235, + 9780, + 9334, + 8899, + 8475, + 8062, + 7661, + 7273, + 6897, + 6534, + 6186, + 5851, + 5531, + 5226, + 4937, + 4663, + 4405, + 4164, + 3939, + 3731, + 3541, + 3367, + 3212, + 3074, + 2955, + 2853, + 2770, + 2705, + 2659, + 2631, + 2621, +}; + +/* +** BinomialWindowTable: +** +** Purpose: +** Binomial Window coefficients used to weight the autocorrelation before +** Levinson-Durbin in the LPC coefficient calculation. +** +** Table Structure: +** Coefficients are scaled by 32768 (Q15). +** +*/ + +Word16 BinomialWindowTable[LpcOrder] = { + 32749, + 32695, + 32604, + 32477, + 32315, + 32118, + 31887, + 31622, + 31324, + 30995, +}; + +/* +** BandExpTable: +** +** Purpose: +** Do bandwidth expansion on the LPC coefficients by scaling the +** poles of the LPC synthesis filter by a factor of 0.994 + +** +** Table Structure: +** Table values correspond to (0.994) to the power of x, +** where x = [0,..,10]. +** These values are scaled by 32768 (Q15). +** +*/ + +Word16 BandExpTable[LpcOrder] = { + 32571, + 32376, + 32182, + 31989, + 31797, + 31606, + 31416, + 31228, + 31040, + 30854, +}; + +/* +** CosineTable: +** +** Purpose: +** Used to evaluate polynomial for LSP-LPC conversion +** +** Table Structure: +** Contains one period of a cosine wave. Amplitude has been +** scaled to go between 0 and 16384 instead of 0 and 1. +** +*/ + +Word16 CosineTable[CosineTableSize] = { + 16384, + 16383, + 16379, + 16373, + 16364, + 16353, + 16340, + 16324, + 16305, + 16284, + 16261, + 16235, + 16207, + 16176, + 16143, + 16107, + 16069, + 16029, + 15986, + 15941, + 15893, + 15843, + 15791, + 15736, + 15679, + 15619, + 15557, + 15493, + 15426, + 15357, + 15286, + 15213, + 15137, + 15059, + 14978, + 14896, + 14811, + 14724, + 14635, + 14543, + 14449, + 14354, + 14256, + 14155, + 14053, + 13949, + 13842, + 13733, + 13623, + 13510, + 13395, + 13279, + 13160, + 13039, + 12916, + 12792, + 12665, + 12537, + 12406, + 12274, + 12140, + 12004, + 11866, + 11727, + 11585, + 11442, + 11297, + 11151, + 11003, + 10853, + 10702, + 10549, + 10394, + 10238, + 10080, + 9921, + 9760, + 9598, + 9434, + 9269, + 9102, + 8935, + 8765, + 8595, + 8423, + 8250, + 8076, + 7900, + 7723, + 7545, + 7366, + 7186, + 7005, + 6823, + 6639, + 6455, + 6270, + 6084, + 5897, + 5708, + 5520, + 5330, + 5139, + 4948, + 4756, + 4563, + 4370, + 4176, + 3981, + 3786, + 3590, + 3393, + 3196, + 2999, + 2801, + 2603, + 2404, + 2205, + 2006, + 1806, + 1606, + 1406, + 1205, + 1005, + 804, + 603, + 402, + 201, + 0, + -201, + -402, + -603, + -804, + -1005, + -1205, + -1406, + -1606, + -1806, + -2006, + -2205, + -2404, + -2603, + -2801, + -2999, + -3196, + -3393, + -3590, + -3786, + -3981, + -4176, + -4370, + -4563, + -4756, + -4948, + -5139, + -5330, + -5520, + -5708, + -5897, + -6084, + -6270, + -6455, + -6639, + -6823, + -7005, + -7186, + -7366, + -7545, + -7723, + -7900, + -8076, + -8250, + -8423, + -8595, + -8765, + -8935, + -9102, + -9269, + -9434, + -9598, + -9760, + -9921, + -10080, + -10238, + -10394, + -10549, + -10702, + -10853, + -11003, + -11151, + -11297, + -11442, + -11585, + -11727, + -11866, + -12004, + -12140, + -12274, + -12406, + -12537, + -12665, + -12792, + -12916, + -13039, + -13160, + -13279, + -13395, + -13510, + -13623, + -13733, + -13842, + -13949, + -14053, + -14155, + -14256, + -14354, + -14449, + -14543, + -14635, + -14724, + -14811, + -14896, + -14978, + -15059, + -15137, + -15213, + -15286, + -15357, + -15426, + -15493, + -15557, + -15619, + -15679, + -15736, + -15791, + -15843, + -15893, + -15941, + -15986, + -16029, + -16069, + -16107, + -16143, + -16176, + -16207, + -16235, + -16261, + -16284, + -16305, + -16324, + -16340, + -16353, + -16364, + -16373, + -16379, + -16383, + -16384, + -16383, + -16379, + -16373, + -16364, + -16353, + -16340, + -16324, + -16305, + -16284, + -16261, + -16235, + -16207, + -16176, + -16143, + -16107, + -16069, + -16029, + -15986, + -15941, + -15893, + -15843, + -15791, + -15736, + -15679, + -15619, + -15557, + -15493, + -15426, + -15357, + -15286, + -15213, + -15137, + -15059, + -14978, + -14896, + -14811, + -14724, + -14635, + -14543, + -14449, + -14354, + -14256, + -14155, + -14053, + -13949, + -13842, + -13733, + -13623, + -13510, + -13395, + -13279, + -13160, + -13039, + -12916, + -12792, + -12665, + -12537, + -12406, + -12274, + -12140, + -12004, + -11866, + -11727, + -11585, + -11442, + -11297, + -11151, + -11003, + -10853, + -10702, + -10549, + -10394, + -10238, + -10080, + -9921, + -9760, + -9598, + -9434, + -9269, + -9102, + -8935, + -8765, + -8595, + -8423, + -8250, + -8076, + -7900, + -7723, + -7545, + -7366, + -7186, + -7005, + -6823, + -6639, + -6455, + -6270, + -6084, + -5897, + -5708, + -5520, + -5330, + -5139, + -4948, + -4756, + -4563, + -4370, + -4176, + -3981, + -3786, + -3590, + -3393, + -3196, + -2999, + -2801, + -2603, + -2404, + -2205, + -2006, + -1806, + -1606, + -1406, + -1205, + -1005, + -804, + -603, + -402, + -201, + 0, + 201, + 402, + 603, + 804, + 1005, + 1205, + 1406, + 1606, + 1806, + 2006, + 2205, + 2404, + 2603, + 2801, + 2999, + 3196, + 3393, + 3590, + 3786, + 3981, + 4176, + 4370, + 4563, + 4756, + 4948, + 5139, + 5330, + 5520, + 5708, + 5897, + 6084, + 6270, + 6455, + 6639, + 6823, + 7005, + 7186, + 7366, + 7545, + 7723, + 7900, + 8076, + 8250, + 8423, + 8595, + 8765, + 8935, + 9102, + 9269, + 9434, + 9598, + 9760, + 9921, + 10080, + 10238, + 10394, + 10549, + 10702, + 10853, + 11003, + 11151, + 11297, + 11442, + 11585, + 11727, + 11866, + 12004, + 12140, + 12274, + 12406, + 12537, + 12665, + 12792, + 12916, + 13039, + 13160, + 13279, + 13395, + 13510, + 13623, + 13733, + 13842, + 13949, + 14053, + 14155, + 14256, + 14354, + 14449, + 14543, + 14635, + 14724, + 14811, + 14896, + 14978, + 15059, + 15137, + 15213, + 15286, + 15357, + 15426, + 15493, + 15557, + 15619, + 15679, + 15736, + 15791, + 15843, + 15893, + 15941, + 15986, + 16029, + 16069, + 16107, + 16143, + 16176, + 16207, + 16235, + 16261, + 16284, + 16305, + 16324, + 16340, + 16353, + 16364, + 16373, + 16379, + 16383, +}; + +/* +** LspDcTable: LSP long term Dc component +** +*/ + +Word16 LspDcTable[LpcOrder] = { + 0x0c3b, + 0x1271, + 0x1e0a, + 0x2a36, + 0x3630, + 0x406f, + 0x4d28, + 0x56f4, + 0x638c, + 0x6c46, +}; + +/* +** BandInfoTable: +** +** Purpose: +** Used to index in arrays. Called by LSP sub vector +** quantization routines. +** +** Table Structure: +** The unquantized LSP vector, quantized LSP vector, and residual +** LSP error vector are each divided into three subvectors. +** The table format is as follows: +** +** 1st pair corresponds to subvector 0 +** 2nd pair corresponds to subvector 1 +** 3rd pair corresponds to subvector 2 +** +** The 1st slot in each pair is used to index the location of +** the vector in a 10-element array. For example, for subvector +** 1, dimensions [0,..,2] get automatically mapped to array +** location [3,..,5], and for subvector 3, dimensions +** [0,..,3] automatically get mapped to array location [6,..,9]. +** +** The 2nd slot in each pair corresponds to the dimension of +** the subvector +*/ + +Word16 BandInfoTable[LspQntBands][2] = { + {0, 3} + , + {3, 3} + , + {6, 4} +}; + +/* +** Band0Tb8: +** +** Purpose: +** Vector Quantize the first 3-vector of the 10 LSP parameters. +** +** Table Structure: +** 8 bit, 256 entry table. +*/ + +Word16 Band0Tb8[LspCbSize * 3] = { + 0, 0, 0, + -270, -1372, -1032, + -541, -1650, -1382, + -723, -2011, -2213, + -941, -1122, -1942, + -780, -1145, -2454, + -884, -1309, -1373, + -1051, -1523, -1766, + -1083, -1622, -2300, + -777, -1377, -2147, + -935, -1467, -2763, + -802, -1327, -3471, + -935, -1959, -3999, + -240, -89, 222, + -661, -257, -160, + -994, -466, -419, + -188, -164, -278, + -342, -512, -415, + -607, -511, -797, + 16, 19, -716, + 374, 425, -972, + -346, 245, -282, + -265, 506, -754, + -620, -147, 1955, + -742, -860, 2597, + -150, -352, 2704, + 305, 880, 1954, + 123, 731, 2766, + -348, 765, 3327, + 618, 221, 3258, + -178, -47, 4219, + 393, 1304, 3842, + 698, 1702, 4801, + 63, -584, 1229, + -215, -732, 1704, + 172, -335, 1909, + -2, 216, 1797, + 353, 127, 2205, + -1208, 188, 11, + -513, -75, -683, + -973, 222, -646, + -616, -843, -388, + -950, -1113, -359, + -1431, -623, -705, + -1398, -1063, -178, + -45, -461, 35, + -9, -657, -216, + 127, -1078, 95, + -950, -1156, 584, + -1480, -1494, 449, + -120, -705, 516, + -368, -961, 727, + -378, -526, 973, + -793, -614, 676, + -801, -755, 1287, + -1476, -340, 1636, + -505, -1254, 1543, + -1243, -1622, 1532, + -776, -1477, -655, + -1151, -1296, -823, + -1153, -1672, -1124, + -1291, -2003, -1702, + -622, -1283, 57, + -471, -1611, 509, + -1060, -1570, -139, + -873, -2156, -536, + -1716, -2021, -364, + -2150, -3218, -1291, + -1248, -1945, -2904, + -1215, -2633, -2855, + 167, -244, 84, + 349, -412, -217, + -40, -352, 632, + 227, -529, 405, + 68, -383, -443, + 167, -558, -706, + -275, -854, -14, + -351, -1089, -449, + 341, -72, -289, + 603, -106, -474, + 322, -219, -649, + 179, -317, -998, + 450, -291, -996, + 555, 195, -525, + 784, 272, -831, + -148, -384, -849, + 82, -536, -1357, + 238, -172, -1354, + 422, -268, -1841, + 297, -737, -2079, + -111, -801, -598, + 1, -668, -984, + -131, -818, -1299, + -329, -521, -1310, + -151, -778, -1834, + -93, -352, -1746, + -568, -640, -1821, + -509, -941, -2183, + 464, -815, -1250, + 79, -1133, -1597, + -184, -1353, -2123, + -196, -410, -2427, + -192, -833, -2810, + -259, -1382, -3045, + -217, 4, -1166, + -800, -325, -1219, + -363, -830, -898, + -661, -1134, -960, + -386, -980, -1501, + -627, -1159, -1722, + -903, -829, -855, + -685, -829, -1313, + -1065, -959, -1405, + 441, 25, -847, + 655, -27, -1181, + 1159, -110, -705, + 856, 253, -1671, + 415, 404, -1, + 322, 903, -398, + 670, 499, -292, + 803, 591, -610, + 1144, 591, -814, + 717, 183, 393, + 857, 381, 106, + 609, 62, -27, + 792, 198, -325, + 735, 805, 88, + 1142, 812, 78, + 1028, 366, -292, + 1309, 743, -237, + 1615, 589, -79, + 1010, 639, -243, + 999, 964, -311, + 1500, 1137, -615, + 988, 357, 646, + 1227, 667, 683, + 1164, 1565, 894, + 1392, 2015, 477, + 1138, 533, 250, + 1437, 896, 391, + 1765, 1118, 99, + 1112, 1090, 802, + 1596, 846, 1134, + 937, 1161, 279, + 1719, 1254, 683, + 1338, 1086, 35, + 1419, 1324, 428, + 1428, 1524, 40, + 2108, 1594, 89, + 1015, 544, 1222, + 1121, 925, 1263, + 1030, 1318, 1485, + 1295, 789, 1817, + 1323, 1272, 1909, + 1724, 1237, 1803, + 1797, 1689, 858, + 2149, 1367, 1301, + 2302, 1867, 761, + 2863, 2351, 1053, + 52, 163, -76, + 230, 309, -492, + -71, 619, 39, + -218, 856, 499, + -654, 736, -207, + -535, 1259, 155, + -480, 1476, 643, + 262, 1081, 102, + 309, 1592, -182, + 627, 1629, 534, + 337, 643, 456, + 758, 670, 713, + 202, 1126, 658, + 612, 1131, 666, + 686, 1223, 1136, + -131, 377, 525, + 42, 708, 907, + 87, 1488, 1035, + 432, 2117, 904, + 137, 981, 1332, + -447, 1014, 1136, + -839, 1793, 1246, + -559, 297, 198, + -850, 685, 446, + -1273, 632, 826, + -401, -544, 173, + -753, -793, 144, + -436, -9, 772, + -115, -243, 1310, + -670, -269, 374, + -1027, -13, 639, + -887, -81, 1137, + -1277, -455, 158, + -1411, -720, 736, + 172, 88, 403, + 386, 255, 756, + -500, 522, 910, + -958, 659, 1388, + -395, 301, 1344, + -356, 768, 1813, + -613, 841, 2419, + 445, -122, 252, + 629, -87, 723, + 283, -253, 870, + 456, -116, 1381, + 757, 180, 1059, + 532, 408, 1509, + 947, 288, 1806, + 1325, 994, 2524, + 892, 1219, 3023, + 1397, 1596, 3406, + 1143, 1552, 2546, + 1850, 1433, 2710, + -10, 134, 1002, + 154, 499, 1323, + 508, 792, 1117, + 509, 1340, 1616, + 762, 862, 1608, + 787, 740, 2320, + 794, 1727, 1283, + 465, 2108, 1660, + -120, 1451, 1613, + -386, 2016, 2169, + 891, 1225, 2050, + 456, 1480, 2185, + 1493, 1283, 1209, + 1397, 1636, 1518, + 1776, 1738, 1552, + 1572, 1698, 2141, + 1389, 2126, 1271, + 1959, 2413, 1119, + 1365, 2892, 1505, + 2206, 1971, 1623, + 2076, 1950, 2280, + 1717, 2291, 1867, + 2366, 2515, 1953, + 2865, 2838, 2522, + 2535, 3465, 2011, + 3381, 4127, 2638, + 836, 2667, 2289, + 1761, 2773, 2337, + 1415, 3325, 2911, + 2354, 3138, 3126, + 2659, 4192, 4010, + 1048, 1786, 1818, + 1242, 2111, 2240, + 1512, 2079, 2780, + 1573, 2491, 3138, + 2230, 2377, 2782, + 416, 1773, 2704, + 725, 2336, 3297, + 1252, 2373, 3978, + 2094, 2268, 3568, + 2011, 2712, 4528, + 1341, 3507, 3876, + 1216, 3919, 4922, + 1693, 4793, 6012, +}; + + + +/* +** Band1Tb8: +** +** Purpose: +** Vector Quantize the second 3-vector of the 10 LSP parameters. +** +** Table Structure: +** 8 bit, 256 entry table. +*/ + +Word16 Band1Tb8[LspCbSize * 3] = { + 0, 0, 0, + -2114, -1302, 76, + -2652, -1278, -1368, + -2847, -828, -349, + -3812, -2190, -349, + -3946, -364, -449, + -2725, -4492, -3607, + -3495, -4764, -1744, + -51, -756, 84, + -153, -1191, 504, + 108, -1418, 1167, + -835, -896, 390, + -569, -1702, 87, + -1151, -1818, 933, + -1826, -2547, 411, + -1842, -1818, 1451, + -2438, -1611, 781, + -2747, -2477, 1311, + -940, 1252, 477, + -1629, 1688, 602, + -1202, 617, 280, + -1737, 393, 580, + -1528, 1077, 1199, + -2165, -161, 1408, + -2504, -1087, 2371, + -3458, -175, 1395, + -1397, -98, -843, + -2252, -177, -1149, + -1489, -726, -1283, + -1558, -265, -1744, + -1867, -821, -1897, + -2062, -1516, -2340, + -2595, -1142, -2861, + 170, 46, -819, + -193, -204, -1151, + 326, -196, -1532, + 780, 329, -816, + 201, 369, -1243, + 650, -209, -1060, + 1144, -15, -1216, + 1203, -259, -1867, + -890, -564, -1430, + -638, -852, -1921, + 177, -739, -1358, + -261, -526, -1666, + 206, -407, -2255, + 338, -526, -822, + 421, -1095, -1009, + 765, -607, -1408, + 825, -1295, -2004, + 357, -905, -1815, + -58, -1248, -1588, + -596, -1436, -2046, + -73, -1159, -2116, + -115, -1382, -2581, + -160, -1723, -1952, + -6, -2196, -2954, + -649, -1705, -2603, + -617, -1453, -3282, + -949, -2019, -3102, + -812, 1544, 1937, + -1854, 574, 2000, + -1463, 1140, 2649, + -2683, 1748, 1452, + -2486, 2241, 2523, + 783, 1910, 1435, + 581, 2682, 1376, + 236, 2197, 1885, + -453, 2943, 2057, + -682, 2178, 2565, + -1342, 3201, 3328, + -288, -184, 262, + 121, -149, -183, + 758, -412, 206, + 1038, -204, 853, + 1577, -457, 700, + 937, -640, -567, + 1508, -528, -1024, + -225, -527, -427, + -564, -1095, -332, + -742, -353, -186, + -1288, -459, 84, + -1853, -484, -274, + -1554, -731, 825, + -2425, -234, 382, + -1722, 293, -271, + -2515, 425, -564, + -2599, 818, 464, + -358, 118, -375, + -613, 198, -874, + -690, 683, -324, + -1352, 1155, -168, + -1093, 129, -324, + -1184, 611, -858, + 433, 386, -372, + -120, 486, -634, + 234, 851, -631, + 602, 128, 46, + 1099, 410, 159, + 715, -145, -424, + 1198, -85, -593, + 1390, 367, -358, + 1683, 362, -964, + 1711, 622, 45, + 2033, 833, -383, + 2890, 549, -506, + 7, 401, 52, + 72, 811, 415, + 566, 668, 41, + 467, 1218, 130, + 68, 957, -187, + -25, 1649, -103, + -661, 260, 214, + -925, -94, 612, + -321, -422, 965, + -788, -672, 1783, + 400, -673, 779, + 741, -595, 1635, + -161, 307, 657, + -382, 836, 871, + -814, 400, 1223, + 364, 606, 1247, + 57, 75, 1571, + 151, 471, 2287, + -81, 1021, 1502, + 227, 1470, 1097, + 658, 1275, 1653, + 664, 1478, 2377, + 263, -127, 444, + 264, 89, 969, + 794, 171, 576, + 821, 186, 1226, + 404, 462, 517, + 339, 918, 794, + 1280, 1423, 196, + 1453, 2019, 365, + 1615, 1481, 672, + 2394, 1708, 508, + 806, 1238, 573, + 713, 1158, 1078, + 1285, 1436, 1232, + 1790, 1188, 1141, + 765, 643, 864, + 1032, 797, 1279, + 900, 563, 1827, + 1514, 673, 2312, + 1544, 1129, 3240, + 1469, 1050, 1594, + 1945, 1318, 1988, + 2397, 2026, 2060, + 3538, 2057, 2620, + 1249, -118, 74, + 1727, 194, 421, + 2078, -50, -463, + 970, 688, -432, + 1149, 952, -110, + 1254, 1275, -651, + 1386, 929, 401, + 1960, 1167, 232, + 407, -752, -243, + 859, -1118, 172, + -227, -860, -992, + -796, -1175, -1380, + 8, -1282, -388, + 353, -1781, -1037, + -732, -397, -807, + -853, -28, -1342, + -1229, -1207, -1959, + -1015, -1125, -2543, + -1452, -1791, -2725, + -1891, -2416, -3269, + -918, -1629, -783, + -580, -2155, -698, + -1097, -2364, -96, + -1387, -1513, 7, + -1588, -2076, -664, + -1473, -2740, -784, + -2378, -3149, -56, + -2856, -2092, -169, + -3391, -3708, 316, + -1176, -890, -614, + -1944, -1061, -800, + -299, -1517, -1000, + -640, -1850, -1526, + -1454, -1536, -1233, + -1890, -1955, -1756, + -1086, -1921, -2122, + -750, -2325, -2260, + -1325, -2413, -2673, + -1114, -2542, -3459, + -1341, -2901, -3963, + -1160, -2226, -1393, + -1001, -2772, -1573, + -1594, -2641, -1978, + -1534, -3046, -2624, + -2224, -2196, -675, + -2807, -3054, -1102, + -2008, -2840, -1186, + -1980, -3332, -1695, + -1715, -3562, -505, + -2527, -4000, -1887, + -2333, -2734, -2296, + -3440, -2401, -3211, + -2008, -3528, -3337, + -2247, -3291, -4510, + -475, 949, 155, + -149, 1365, 545, + -757, 1644, 1083, + -217, 2053, 1353, + -1433, 2301, 1462, + 495, 1661, 529, + 10, 2037, 740, + 2082, 1898, 978, + 2831, 2294, 911, + 842, 793, 420, + 1223, 1023, 863, + 1237, 451, 780, + 1744, 708, 822, + 1533, 284, 1384, + 2135, 609, 1538, + 2305, 626, 540, + 2368, 1187, 955, + 2586, 1255, -7, + 3116, 1131, 726, + 3431, 1730, 428, + 2734, 1648, 1307, + 2988, 1231, 2010, + 3523, 2024, 1488, + 1034, 1657, 871, + 1206, 2163, 1036, + 1807, 2372, 1233, + 1808, 1769, 1493, + 1573, 2332, 1779, + 1216, 1609, 1866, + 1480, 1898, 2513, + 465, 2708, 2776, + 771, 3638, 3338, + 1869, 2599, 2623, + 2825, 2745, 2468, + 2638, 2439, 1585, + 2094, 2970, 1308, + 2022, 3057, 1999, + 3428, 2912, 1816, + 4536, 2974, 2129, + 1046, 2563, 2086, + 1363, 3562, 2318, + 2511, 1891, 2984, + 1866, 2306, 3986, + 3272, 2924, 3682, + 3146, 3564, 2272, + 3592, 3968, 2822, + 2431, 3369, 3069, + 1931, 4709, 3090, + 2629, 4220, 3986, + 4639, 4056, 3664, + 4035, 5334, 4912, +}; + + +/* +** Band2Tb8: +** +** Purpose: +** Vector Quantize the last 4-vector of the 10 LSP parameters. +** +** Table Structure: +** 8 bit, 256 entry table. +*/ + +Word16 Band2Tb8[LspCbSize * 4] = { + 0, 0, 0, 0, + 601, 512, -542, 334, + 428, 1087, -484, -132, + 652, 622, -391, -572, + 378, 799, 141, -860, + 1040, 409, 112, -554, + 1123, 670, -75, -847, + 1421, 494, -315, -1095, + 787, 1001, 114, -460, + 988, 1672, 216, -681, + 1007, 1241, -132, -1247, + 1073, 399, 186, -5, + 1262, 193, -694, -129, + 325, 196, 51, -641, + 861, -59, 350, -458, + 1261, 567, 586, -346, + 1532, 885, 210, -517, + 2027, 937, 113, -792, + 1383, 1064, 334, 38, + 1964, 1468, 459, 133, + 2062, 1186, -98, -121, + 2577, 1445, 506, -373, + 2310, 1682, -2, -960, + 2876, 1939, 765, 138, + 3581, 2360, 649, -414, + 219, 176, -398, -309, + 434, -78, -435, -880, + -344, 301, 265, -552, + -915, 470, 657, -380, + 419, -432, -163, -453, + 351, -953, 8, -562, + 789, -43, 20, -958, + 302, -594, -352, -1159, + 1040, 108, -668, -924, + 1333, 210, -1217, -1663, + 483, 589, -350, -1140, + 1003, 824, -802, -1184, + 745, 58, -589, -1443, + 346, 247, -915, -1683, + 270, 796, -720, -2043, + 1208, 722, -222, -193, + 1486, 1180, -412, -672, + 1722, 179, -69, -521, + 2047, 860, -666, -1410, + -146, 222, -281, -805, + -189, 90, -114, -1307, + -152, 1086, -241, -764, + -439, 733, -601, -1302, + -833, -167, -351, -601, + -856, -422, -411, -1059, + -747, -355, -582, -1644, + -837, 210, -916, -1144, + -1800, 32, -878, -1687, + -48, -23, -1146, 52, + -350, -409, -1656, -364, + 265, -728, -858, -577, + 458, -247, -1141, -997, + 691, -407, -1988, -1161, + -66, -104, -705, -1249, + -431, -93, -1191, -1844, + 203, -732, -1000, -1693, + 10, -832, -1846, -1819, + 493, -128, -1436, -1768, + 488, -311, -1730, -2540, + -653, -532, -1150, -1172, + -1086, -289, -1706, -1533, + -699, -1205, -1216, -1766, + -1032, -1481, -2074, -1523, + -721, -1220, -2277, -2600, + 12, -539, -1484, -1131, + -40, -911, -2106, -441, + -471, -484, -2267, -1549, + -141, -988, -3006, -1721, + -1545, -2102, -583, 342, + -1383, -2772, -386, -13, + -2118, -2589, -1205, 72, + -2147, -3231, -965, 390, + -2949, -3300, -621, 637, + -3907, -4138, -865, 803, + -1287, -845, -375, -548, + -1416, -1169, -487, -1277, + -1400, -1690, -1027, -418, + -2018, -1909, -1188, -1260, + -1418, -2222, -2029, -128, + -2067, -2998, -2693, -310, + -950, -1028, -1538, 185, + -1616, -915, -2205, -549, + 19, -821, -1145, 352, + 184, -1175, -1356, -627, + -547, -1088, -1661, -911, + -216, -1502, -2197, -948, + -795, -1306, -2374, -451, + -924, -1889, -2796, -680, + -600, -1614, -3609, -885, + -2392, -2528, 319, 303, + -2908, -2095, -310, 573, + -3460, -2141, 49, -113, + -2231, -448, 675, -146, + -2805, -532, 1231, 479, + -2684, -486, -200, 611, + -3525, -971, -198, 704, + -3707, 173, 349, 254, + -4734, -1447, -34, 880, + 777, -512, 114, -10, + 1250, -66, 442, -5, + 604, 613, 452, -352, + 1224, 777, 675, -1014, + -1372, -79, -1208, -238, + -2389, -17, -1157, -818, + -1504, -673, -1133, -1060, + -1984, -799, -2005, -1973, + -2037, -798, -1068, -105, + -3190, -899, -1817, -194, + -156, -886, 394, -318, + -258, -1283, 551, 202, + -536, -1729, 910, 331, + -847, -1109, 795, -163, + -1171, -1128, 715, 519, + -1080, -1319, 1685, 668, + -1000, -1921, 96, 211, + -1487, -2148, 831, 174, + -1139, -374, 414, -4, + -1517, -1383, 396, -352, + -1012, 439, -59, -967, + -1812, 706, -440, -1030, + -1971, -329, -34, -827, + -2472, -1588, -151, -606, + -2161, 374, -281, 76, + -3012, 231, -15, -690, + 1104, 566, 721, 209, + 1685, 564, 383, 98, + 1898, 750, 792, -97, + 556, -64, 561, -93, + 876, 162, 913, -22, + 961, 675, 1296, 140, + 756, -396, 851, 544, + 360, -303, 1341, 396, + 878, -22, 1464, 863, + -309, -273, 642, -129, + -686, -82, 842, 454, + -5, -47, 1069, 998, + -94, 967, 1277, 298, + -489, 385, 1473, 746, + -369, -717, 1333, 242, + 281, -993, 1726, 924, + 464, 601, 1575, 1376, + -250, 206, 2339, 1175, + -438, 377, -597, -285, + -1020, 787, -790, -287, + -458, -410, 215, 295, + -589, -860, -121, 797, + -1175, 122, -437, 466, + -1480, -121, 367, 924, + 234, 323, 770, -555, + 145, 30, 996, 26, + 66, 849, 93, -145, + -117, 1261, 474, -399, + -1495, 1051, 218, -506, + -1390, 694, 994, 88, + 616, 7, 78, 304, + 1060, 52, -62, 835, + 833, 454, 649, 1359, + -770, 464, 47, 93, + -574, 1199, -39, 379, + 114, -98, 488, 485, + 727, 244, 606, 696, + -76, 455, 671, 546, + -565, -13, 145, 819, + -376, 569, 448, 1128, + 218, 122, 265, 1167, + 230, 738, 932, 1003, + 138, 477, 36, 450, + 404, 787, -73, 1000, + 497, 1259, 387, 1231, + 17, 207, 195, -79, + 562, 358, 53, -158, + 493, 387, 478, 189, + 678, 831, 640, 558, + -197, 523, 613, 57, + 429, 894, 769, 111, + 67, 1174, 568, 511, + 1242, 824, 251, 840, + 1419, 1074, 864, 481, + 924, 1474, 669, 724, + 1539, 1879, 654, 1590, + 445, 337, 1111, 541, + 472, 1421, 1264, 1094, + 794, 735, 1103, 668, + 1055, 863, 1192, 1020, + 778, 1105, 806, 1798, + 1052, 1527, 1587, 2151, + 881, 1552, 1265, 391, + 726, 872, 1812, 601, + 1469, 280, 1008, 616, + 1403, 577, 1803, 1244, + 1650, 1314, 1148, 1072, + 1297, 1669, 1911, 1026, + 2093, 1044, 2115, 1189, + 1644, 1961, 2587, 1512, + 25, -315, -9, -106, + 290, -339, 428, -444, + -68, -783, 735, 772, + 245, -555, 468, 47, + 334, -895, 814, 146, + 235, 368, -964, -959, + -203, 315, -1566, -1217, + 801, 17, -276, -354, + 894, -495, -789, -635, + 716, 291, -1189, -357, + 560, -260, -733, -2, + 679, -508, -1429, 211, + -51, -62, -428, 557, + 322, -638, -211, 614, + -878, -1057, -84, -71, + -388, -1415, -167, -318, + -754, -1574, 214, -539, + -1419, -2004, -92, -787, + -47, -856, -347, -255, + 23, -1211, -173, 320, + -658, -487, -893, 353, + -783, -1587, -584, 507, + -1420, -859, -378, 441, + -2095, -1491, -137, 439, + -321, -1450, -1288, -12, + -359, -2113, -553, -8, + -831, -1918, -1561, 32, + -1014, -2487, -1359, -939, + -475, -311, -169, -236, + -907, -426, 276, -611, + -96, -400, 50, -710, + -426, -1022, -10, -985, + -197, -258, -744, -575, + -611, -930, -771, -394, + -267, -776, -612, -939, + -256, -1346, -802, -1122, + -796, -1570, -825, -754, + 712, 876, 141, 227, + 981, 1509, 85, 124, + 1462, 1228, 979, -39, + 1734, 999, 1481, 440, + 2293, 1116, 769, 440, + 2504, 1480, 1241, 356, + 2474, 1909, 1558, 810, + 917, 1134, 607, -134, + 509, 1809, 781, -123, + 1712, 1506, 559, -423, + 2037, 2317, 726, -155, + 3031, 2676, 1203, 331, + 3664, 3274, 1768, 531, + 1610, 1839, 867, 183, + 1774, 1972, 1538, 97, + 1822, 2158, 1282, 659, + 2222, 2758, 1818, 900, + 3251, 2124, 1723, 996, + 3633, 2336, 2408, 1453, + 2923, 3517, 2567, 1318, +}; + +/* +** BandQntTable: +** +** Purpose: +** collects the three subvector tables. +*/ + + +Word16 *BandQntTable[LspQntBands] = { + Band0Tb8, + Band1Tb8, + Band2Tb8, +}; + +/* +** PerFiltZeroTable: +** +** Purpose: +** Creates the FIR part of the formant perceptual weighting filter. +** Corresponds to gamma1 in section 2.8. +** +** Table Structure: +** (0.9) to the x power, where x = [1,..,10] +** These values are scaled by 32768. +*/ + +Word16 PerFiltZeroTable[LpcOrder] = { + 29491, + 26542, + 23888, + 21499, + 19349, + 17414, + 15673, + 14106, + 12695, + 11425, +}; + +/* +** PerFiltPoleTable: +** +** Purpose: +** Creates the IIR part of the formant perceptual weighting filter. +** Corresponds to gamma2 in section 2.8. +** +** Table Structure: +** (0.5) to the x power, where x = [1,..,10] +** These values are scaled by 32768 +*/ + +Word16 PerFiltPoleTable[LpcOrder] = { + 16384, + 8192, + 4096, + 2048, + 1024, + 512, + 256, + 128, + 64, + 32, +}; + +/* +** PostFiltZeroTable: +** +** Purpose: +** Creates the FIR part of the formant postfilter. Corresponds to +** lambda1 in section 3.8. +** +** Table Structure: +** (0.65) to the x power, where x = [1,..,10] +** These values are scaled by 32768 +*/ + +Word16 PostFiltZeroTable[LpcOrder] = { + 21299, + 13844, + 8999, + 5849, + 3802, + 2471, + 1606, + 1044, + 679, + 441, +}; + +/* +** PostFiltPoleTable: +** +** Purpose: +** Creates the IIR part of the formant postfilter. Corresponds to +** lambda2 in section 3.8. +** +** Table Structure: +** (0.75) to the x power, where x = [1,..,10] +** These values are scaled by 32768 +*/ + +Word16 PostFiltPoleTable[LpcOrder] = { + 24576, + 18432, + 13824, + 10368, + 7776, + 5832, + 4374, + 3281, + 2460, + 1845, +}; + +/* +** Nb_puls: +** +** Purpose: +** Indexing +** +** Table Structure: +** Table values are the number of non-zero pulses in the high-rate +** excitation (MP-MLQ), indexed by subframe number (0,..,3). +*/ + +Word16 Nb_puls[4] = { 6, 5, 6, 5 }; + +/* +** FcbkGainTable: +** +** Purpose: +** Logarithmic scalar quantizer in 24 steps of 3.2 dB each +** +** Table Structure: +** Contains x where 20*log10(x) = 3.2*i, i = 1,..,24 +*/ + +Word16 FcbkGainTable[NumOfGainLev] = { + 1, + 2, + 3, + 4, + 6, + 9, + 13, + 18, + 26, + 38, + 55, + 80, + 115, + 166, + 240, + 348, + 502, + 726, + 1050, + 1517, + 2193, + 3170, + 4582, + 6623, +}; + +/* +** MaxPosTable: +** +** Purpose: +** size of the high rate fixed excitation codebooks (MP-MLQ) +** +** Table Structure: +** Table values are the number of codewords in the high rate fixed +** excitation codebook (MP-MLQ), indexed by subframe number (0,..,3). +** MaxPosTable[i] is the number of combinations of i elements among 30 +** non-zero pulses in the high-rate +*/ + +Word32 MaxPosTable[4] = { + 0x00090f6fL, + 0x00022caaL, + 0x00090f6fL, + 0x00022caaL, +}; + +/* +** CombinatorialTable: +** +** Purpose: +** used for the coding and the decoding of the pulses positions +** for the high-rate fixed excitation codebook +** +** Table Structure: +** CombinatorialTable[i][j] is the number of combinations of +** (MaxPulsNum-1-i) elements among (SubFrLen-2-j) +*/ + +Word32 CombinatorialTable[MaxPulseNum][SubFrLen / Sgrid] = { + {118755L, + 98280L, + 80730L, + 65780L, + 53130L, + 42504L, + 33649L, + 26334, + 20349, + 15504, + 11628, + 8568, + 6188, + 4368, + 3003, + 2002, + 1287, + 792, + 462, + 252, + 126, + 56, + 21, + 6, + 1, + 0, + 0, + 0, + 0, + 0} + , + + {23751, + 20475, + 17550, + 14950, + 12650, + 10626, + 8855, + 7315, + 5985, + 4845, + 3876, + 3060, + 2380, + 1820, + 1365, + 1001, + 715, + 495, + 330, + 210, + 126, + 70, + 35, + 15, + 5, + 1, + 0, + 0, + 0, + 0} + , + + {3654, + 3276, + 2925, + 2600, + 2300, + 2024, + 1771, + 1540, + 1330, + 1140, + 969, + 816, + 680, + 560, + 455, + 364, + 286, + 220, + 165, + 120, + 84, + 56, + 35, + 20, + 10, + 4, + 1, + 0, + 0, + 0} + , + + {406, + 378, + 351, + 325, + 300, + 276, + 253, + 231, + 210, + 190, + 171, + 153, + 136, + 120, + 105, + 91, + 78, + 66, + 55, + 45, + 36, + 28, + 21, + 15, + 10, + 6, + 3, + 1, + 0, + 0} + , + + {29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0} + , + + {1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1} + , +}; + +/* +** AcbkGainTable085: +** +** Purpose: +** Used to calculate the error expression in pitch prediction +** optimization (also described as an adaptive codebook approach) +** +** Table Structure: +** The table is structured as 85 20-element vectors. These +** vectors are structured as precalculated values in the error +** expression for the pitch predictor. Gi is the gain value +** multiplying the signal delayed by a pitch period (+/- offset). +** In equation 41.2, Gi would be equivalent to bij. +** +** 1st 5 elements: G1 G2 G3 G4 G5 in Q14 (i.e. scaled by 16384) +** 2nd 5 elements: -G1^2 -G2^2 -G3^2 -G4^2 -G5^2 +** These are scaled down by 14 bits (factor of 16384) after +** being squared. +** Next 10 elements: These are the off-diagonal elements +** -G1*G2 -G1*G3 -G2*G3 -G1*G4 -G2*G4 +** -G3*G4 -G1*G5 -G2*G5 -G3*G5 -G4*G5 +** These are scaled down by 14 bits (factor of 16384) +*/ + +Word16 AcbkGainTable085[85 * 20] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 800, 1496, 167, -256, + -338, -39, -136, -1, -4, -6, -73, -8, + -15, 12, 23, 2, 16, 30, 3, -5, + -462, -686, 493, 2575, 311, -13, -28, -14, + -404, -5, -19, 13, 20, 72, 107, -77, + 8, 13, -9, -48, 1483, 144, 784, 928, + 1243, -134, -1, -37, -52, -94, -13, -71, + -6, -84, -8, -44, -112, -10, -59, -70, + -77, 275, 3522, 1056, -1254, 0, -4, -757, + -68, -95, 1, 16, -59, 4, -17, -227, + -5, 21, 269, 80, -125, -40, -264, 381, + 5027, 0, 0, -4, -8, -1542, 0, -2, + 0, 2, 0, 6, 38, 12, 81, -117, + 138, 332, 2215, 2574, 1339, -1, -6, -299, + -404, -109, -2, -18, -44, -21, -52, -348, + -11, -27, -181, -210, 3685, 2883, -887, 866, + -1639, -828, -507, -48, -45, -164, -648, 199, + 156, -194, -152, 46, 368, 288, -88, 86, + 1396, 2146, 2235, 345, 942, -118, -281, -305, + -7, -54, -182, -190, -292, -29, -45, -47, + -80, -123, -128, -19, 13, 4475, 3549, -804, + -655, 0, -1222, -768, -39, -26, -3, -2, + -969, 0, 219, 174, 0, 179, 141, -32, + -724, 254, 242, 6049, 2462, -32, -3, -3, + -2233, -370, 11, 10, -3, 267, -94, -89, + 108, -38, -36, -909, 626, -1713, 6121, 4561, + -1061, -23, -179, -2287, -1270, -68, 65, -233, + 640, -174, 477, -1704, 40, -111, 396, 295, + -350, 1391, 7985, 511, -405, -7, -118, -3892, + -15, -10, 29, 170, -678, 10, -43, -249, + -8, 34, 197, 12, 3144, -529, 608, 2530, + 3878, -603, -17, -22, -390, -918, 101, -116, + 19, -485, 81, -93, -744, 125, -144, -599, + 2589, -689, 3045, 5603, -404, -409, -29, -566, + -1916, -10, 108, -481, 128, -885, 235, -1041, + 63, -17, 75, 138, 3107, 513, 1374, -3594, + -4922, -589, -16, -115, -788, -1478, -97, -260, + -43, 681, 112, 301, 933, 154, 413, -1079, + 2468, 6010, 1107, -390, 1961, -372, -2204, -74, + -9, -234, -905, -166, -406, 58, 143, 26, + -295, -719, -132, 46, 4773, 2766, 2368, 4862, + -4044, -1390, -467, -342, -1443, -998, -806, -690, + -399, -1416, -821, -702, 1178, 682, 584, 1200, + 1665, -1879, 1443, 1701, 8562, -169, -215, -127, + -176, -4475, 190, -146, 165, -172, 195, -149, + -870, 982, -754, -889, 2716, 9011, -1007, 755, + -1785, -450, -4956, -61, -34, -194, -1493, 167, + 554, -125, -415, 46, 296, 982, -109, 82, + -2727, 7548, 1285, 938, 3420, -453, -3478, -100, + -53, -714, 1256, 213, -592, 156, -432, -73, + 569, -1576, -268, -196, 3677, 882, 4050, 1202, + 2323, -825, -47, -1001, -88, -329, -198, -909, + -218, -269, -64, -297, -521, -125, -574, -170, + 2046, -753, 122, 10102, 603, -255, -34, 0, + -6229, -22, 94, -15, 5, -1261, 464, -75, + -75, 27, -4, -372, 449, -1815, 10690, 3870, + -527, -12, -201, -6976, -914, -16, 49, -293, + 1184, -106, 428, -2525, 14, -58, 344, 124, + -941, 2352, 5049, 3650, 2637, -54, -337, -1556, + -813, -424, 135, 290, -725, 209, -524, -1125, + 151, -378, -812, -587, -1879, 796, 3117, 9569, + -404, -215, -38, -593, -5589, -9, 91, 357, + -151, 1097, -464, -1821, -46, 19, 76, 236, + -1715, 2043, -2096, 9946, 4001, -179, -254, -268, + -6038, -977, 213, -219, 261, 1041, -1240, 1272, + 418, -498, 511, -2429, -5772, -618, -3921, 284, + -3155, -2033, -23, -938, -4, -607, -218, -1381, + -148, 100, 10, 68, -1111, -119, -755, 54, + 382, 4748, 8003, -2064, 2198, -8, -1376, -3909, + -260, -294, -110, -186, -2319, 48, 598, 1008, + -51, -637, -1073, 277, -867, 3015, 11926, -1675, + 947, -45, -555, -8681, -171, -54, 159, 631, + -2195, -88, 308, 1219, 50, -174, -690, 96, + -4933, -432, 6757, 3771, 1352, -1485, -11, -2786, + -867, -111, -130, 2034, 178, 1135, 99, -1555, + 407, 35, -557, -311, 152, 9726, 4231, -1928, + 1490, -1, -5774, -1092, -226, -135, -90, -39, + -2511, 17, 1144, 498, -13, -884, -384, 175, + 2512, 193, 9033, 5361, -3148, -385, -2, -4980, + -1754, -605, -29, -1385, -106, -822, -63, -2956, + 482, 37, 1735, 1030, 8464, 2844, 12, 549, + 2132, -4373, -493, 0, -18, -277, -1469, -6, + -2, -284, -95, 0, -1101, -370, -1, -71, + 2141, -2602, 7166, 9046, -1350, -279, -413, -3134, + -4994, -111, 340, -936, 1138, -1182, 1436, -3957, + 176, -214, 590, 745, -244, 278, 13307, 1227, + -161, -3, -4, -10808, -91, -1, 4, 198, + -226, 18, -20, -997, -2, 2, 131, 12, + -1947, 8217, 6269, 917, -2559, -231, -4121, -2399, + -51, -399, 976, 745, -3144, 108, -460, -350, + -304, 1283, 979, 143, -1810, 2061, -2781, 6056, + 10058, -200, -259, -472, -2238, -6174, 227, -307, + 349, 669, -761, 1028, 1111, -1265, 1707, -3717, + 7827, 9161, -3409, 2473, -1510, -3739, -5122, -709, + -373, -139, -4376, 1628, 1906, -1181, -1382, 514, + 721, 844, -314, 228, -1430, 8313, 9541, -2955, + 1626, -124, -4218, -5556, -533, -161, 725, 832, + -4841, -257, 1499, 1721, 142, -825, -947, 293, + 2819, -4247, 5391, 8673, 2756, -485, -1101, -1774, + -4591, -463, 730, -927, 1397, -1492, 2248, -2854, + -474, 714, -907, -1459, 141, 14552, 690, 257, + -112, -1, -12926, -29, -4, 0, -125, -5, + -613, -2, -228, -10, 0, 99, 4, 1, + 11938, -1859, 1806, -962, -884, -8699, -211, -199, + -56, -47, 1355, -1316, 205, 701, -109, 106, + 644, -100, 97, -51, 3728, 1982, 2264, 4584, + 3131, -848, -239, -312, -1282, -598, -451, -515, + -273, -1043, -554, -633, -712, -378, -432, -876, + -1181, 766, 720, 14303, -216, -85, -35, -31, + -12486, -2, 55, 51, -33, 1031, -668, -628, + -15, 10, 9, 189, -4385, 4826, 10112, 1569, + 3388, -1173, -1421, -6242, -150, -700, 1291, 2706, + -2979, 420, -462, -969, 906, -998, -2091, -324, + -448, 1932, 15591, -1842, 657, -12, -227, -14837, + -207, -26, 52, 427, -1838, -50, 217, 1753, + 18, -77, -626, 74, -4141, 1844, 3962, 5517, + 6220, -1046, -207, -958, -1858, -2361, 466, 1001, + -446, 1394, -621, -1334, 1572, -700, -1504, -2094, + 729, -2299, 14755, 3657, -952, -32, -322, -13288, + -816, -55, 102, -656, 2071, -162, 513, -3294, + 42, -133, 857, 212, -1385, 5801, 13339, -3137, + 1344, -117, -2054, -10861, -600, -110, 490, 1127, + -4723, -265, 1111, 2554, 113, -476, -1094, 257, + 4710, 9661, 1073, -2467, 3274, -1354, -5697, -70, + -371, -654, -2777, -308, -633, 709, 1455, 161, + -941, -1930, -214, 493, 1843, -3624, 12422, 6898, + -1559, -207, -802, -9419, -2904, -148, 407, -1397, + 2748, -775, 1526, -5230, 175, -344, 1182, 656, + 1433, 2394, 2507, 1380, 8780, -125, -349, -383, + -116, -4705, -209, -219, -366, -120, -201, -211, + -768, -1283, -1343, -740, -1712, 12915, 5883, -2197, + 991, -179, -10181, -2112, -294, -60, 1350, 615, + -4638, -229, 1732, 789, 103, -781, -356, 133, + 15072, 2158, -1245, 910, -496, -13865, -284, -94, + -50, -15, -1986, 1145, 164, -837, -119, 69, + 456, 65, -37, 27, 4655, 7319, 4916, 586, + -3381, -1322, -3270, -1475, -20, -697, -2079, -1396, + -2196, -166, -261, -175, 960, 1510, 1014, 120, + 1191, -2140, 5120, 13498, -1418, -86, -279, -1600, + -11121, -122, 155, -372, 669, -981, 1763, -4218, + 103, -185, 443, 1168, -1530, -817, 8191, 9632, + -1452, -143, -40, -4095, -5663, -128, -76, 765, + 408, 900, 480, -4815, -135, -72, 726, 854, + -3236, 607, 1696, -2106, 11485, -639, -22, -175, + -270, -8051, 119, 335, -62, -416, 78, 218, + 2268, -425, -1189, 1476, 3203, -1903, -837, 9679, + 7057, -626, -221, -42, -5718, -3039, 372, 163, + -97, -1892, 1124, 494, -1380, 819, 360, -4169, + 213, -655, 17015, 620, -384, -2, -26, -17671, + -23, -9, 8, -221, 681, -8, 24, -644, + 5, -15, 399, 14, 5088, 35, -3339, 3726, + 8488, -1580, 0, -680, -847, -4397, -10, 1037, + 7, -1157, -8, 759, -2636, -18, 1730, -1930, + -988, 1454, -2688, 15039, 2682, -59, -129, -441, + -13805, -439, 87, -162, 238, 907, -1335, 2467, + 161, -238, 440, -2462, -4865, -2842, -53, 5495, + 6523, -1445, -493, 0, -1843, -2597, -844, -16, + -9, 1632, 953, 18, 1937, 1131, 21, -2188, + 3076, 15069, -2914, 1810, -971, -577, -13860, -518, + -200, -57, -2829, 547, 2680, -339, -1665, 322, + 182, 893, -172, 107, 1311, 5355, 11054, 2299, + -3654, -105, -1750, -7458, -322, -814, -428, -885, + -3613, -184, -751, -1551, 292, 1194, 2465, 512, + 4035, 5619, 4618, 1815, 1912, -994, -1927, -1301, + -201, -223, -1384, -1137, -1583, -447, -622, -511, + -471, -656, -539, -211, -2131, 2754, -4501, 12879, + 7432, -277, -463, -1236, -10124, -3371, 358, -585, + 756, 1675, -2165, 3538, 967, -1249, 2042, -5842, + 5618, -515, 3219, -4149, 4857, -1926, -16, -632, + -1050, -1440, 176, -1104, 101, 1422, -130, 815, + -1666, 152, -954, 1230, 1838, -1709, 1139, 16867, + 716, -206, -178, -79, -17366, -31, 191, -127, + 118, -1892, 1759, -1173, -80, 74, -49, -737, + 1978, -3845, 10050, 11854, -2492, -238, -902, -6164, + -8576, -379, 464, -1213, 2358, -1431, 2782, -7271, + 301, -585, 1529, 1803, -2600, 11246, 11289, -3647, + 1463, -412, -7720, -7778, -812, -130, 1784, 1791, + -7749, -578, 2504, 2513, 232, -1004, -1008, 325, + 3442, 907, 2725, 8970, 3638, -723, -50, -453, + -4911, -808, -190, -572, -150, -1884, -496, -1492, + -764, -201, -605, -1992, -126, 17498, 3481, -2003, + 1090, 0, -18689, -739, -244, -72, 135, 26, + -3717, -15, 2139, 425, 8, -1165, -231, 133, + -1814, 1048, -2164, 4070, 16272, -200, -67, -285, + -1011, -16160, 116, -239, 138, 450, -260, 537, + 1801, -1041, 2149, -4042, 9354, 12580, -1883, 962, + -617, -5341, -9660, -216, -56, -23, -7183, 1075, + 1446, -549, -738, 110, 352, 474, -71, 36, + 1708, 4199, 7387, 6335, 1003, -178, -1076, -3330, + -2449, -61, -437, -770, -1893, -660, -1623, -2856, + -104, -257, -452, -388, -2624, 5623, 17310, -2353, + 592, -420, -1930, -18288, -338, -21, 900, 2772, + -5941, -376, 807, 2486, 94, -203, -625, 85, + 1211, -850, 1193, -1926, 15992, -89, -44, -86, + -226, -15609, 62, -88, 61, 142, -100, 140, + -1182, 830, -1165, 1880, 3983, -2054, 11506, -19, + 3622, -968, -257, -8080, 0, -801, 499, -2797, + 1442, 4, -2, 13, -880, 454, -2544, 4, + -786, -1354, 16092, 7246, -1665, -37, -111, -15805, + -3205, -169, -65, 772, 1330, 348, 599, -7117, + -80, -137, 1636, 736, -4316, -511, 6674, 11665, + 4633, -1137, -15, -2719, -8305, -1310, -134, 1758, + 208, 3073, 364, -4752, 1220, 144, -1887, -3299, + 7912, 4557, 1937, 1885, 7037, -3821, -1267, -229, + -216, -3022, -2200, -935, -538, -910, -524, -222, + -3398, -1957, -832, -809, 3434, 2967, 5867, 8196, + 8766, -720, -537, -2101, -4100, -4690, -622, -1230, + -1062, -1718, -1484, -2935, -1837, -1588, -3139, -4385, + 5881, 9176, 8119, 3934, 3355, -2111, -5139, -4023, + -944, -687, -3294, -2914, -4547, -1412, -2203, -1949, + -1204, -1879, -1662, -805 +}; + +/* +** AcbkGainTable170: +** +** Purpose: +** Used to calculate the error expression in pitch prediction +** optimization (also expressed as an adaptive codebook approach) +** +** Table Structure: +** The table is structured as 170 20-element vectors. These +** vectors are structured as precalculated values in the error +** expression for the pitch +** predictor. Gi is the gain value multiplying the signal +** delayed by a pitch period (+/- offset). In equation 41.2, +** Gi would be equivalent to bij. +** +** 1st 5 elements: G1 G2 G3 G4 G5 in Q14 (i.e. scaled by 16384) +** 2nd 5 elements: -G1^2 -G2^2 -G3^2 -G4^2 -G5^2 +** These are scaled down by 14 bits (factor of 16384) after +** being squared. +** Next 10 elements: These are the off-diagonal elements +** -G1*G2 -G1*G3 -G2*G3 -G1*G4 -G2*G4 +** -G3*G4 -G1*G5 -G2*G5 -G3*G5 -G4*G5 +** These are scaled down by 14 bits (factor of 16384) +*/ + +Word16 AcbkGainTable170[170 * 20] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 776, 212, 715, 670, + 809, -36, -2, -31, -27, -39, -10, -33, + -9, -31, -8, -29, -38, -10, -35, -33, + 1296, 1316, -168, -320, -815, -102, -105, -1, + -6, -40, -104, 13, 13, 25, 25, -3, + 64, 65, -8, -15, -589, 680, 2478, 308, + -596, -21, -28, -375, -5, -21, 24, 89, + -102, 11, -12, -46, -21, 24, 90, 11, + -735, -487, -5, 2948, 468, -33, -14, 0, + -530, -13, -21, 0, 0, 132, 87, 0, + 21, 13, 0, -84, 1042, 1730, 1068, 333, + 626, -66, -182, -69, -6, -23, -110, -67, + -112, -21, -35, -21, -39, -66, -40, -12, + 486, -769, 4074, 2825, -1107, -14, -36, -1013, + -487, -74, 22, -120, 191, -83, 132, -702, + 32, -52, 275, 191, 1521, -767, -124, 4320, + 1026, -141, -35, 0, -1139, -64, 71, 11, + -5, -401, 202, 32, -95, 48, 7, -270, + 2425, 1267, 3439, -91, -1166, -359, -98, -722, + 0, -83, -187, -509, -266, 13, 7, 19, + 172, 90, 244, -6, -1251, 975, 173, 4039, + 2005, -95, -58, -1, -996, -245, 74, 13, + -10, 308, -240, -42, 153, -119, -21, -494, + 1820, 632, 1322, 2062, 1031, -202, -24, -106, + -259, -64, -70, -146, -51, -229, -79, -166, + -114, -39, -83, -129, -447, 4904, 244, -315, + -2038, -12, -1467, -3, -6, -253, 134, 6, + -73, -8, 94, 4, -55, 610, 30, -39, + -208, -1102, 463, -448, 5653, -2, -74, -13, + -12, -1950, -14, 5, 31, -5, -30, 12, + 71, 380, -159, 154, 4739, 2600, -1864, 856, + -1554, -1371, -412, -212, -44, -147, -752, 539, + 295, -247, -135, 97, 449, 246, -176, 81, + 1894, 3533, 35, -26, 2145, -219, -762, 0, + 0, -280, -408, -4, -7, 3, 5, 0, + -248, -462, -4, 3, -2699, 1841, 4072, 2443, + 1582, -444, -207, -1012, -364, -152, 303, 670, + -457, 402, -274, -607, 260, -177, -393, -236, + -844, 3358, 6106, -1059, -537, -43, -688, -2275, + -68, -17, 173, 314, -1251, -54, 217, 395, + -27, 110, 200, -34, 1251, 1016, 3020, 2210, + 1445, -95, -63, -556, -298, -127, -77, -230, + -187, -168, -137, -407, -110, -89, -266, -194, + 2099, 2277, 4038, 3533, -2870, -269, -316, -995, + -762, -503, -291, -517, -561, -452, -491, -871, + 367, 399, 707, 619, 400, -1114, 8516, 2422, + -1117, -9, -75, -4426, -358, -76, 27, -208, + 579, -59, 164, -1259, 27, -75, 580, 165, + -4398, -2011, 3912, -2407, 2258, -1180, -247, -934, + -353, -311, -540, 1050, 480, -646, -295, 575, + 606, 277, -539, 331, 1767, -1447, 4240, 6160, + -757, -190, -127, -1097, -2316, -35, 156, -457, + 374, -664, 544, -1594, 81, -66, 195, 284, + 1594, -1463, 1035, 6938, 1920, -155, -130, -65, + -2938, -225, 142, -100, 92, -675, 619, -438, + -186, 171, -121, -813, -562, 4716, 4085, -591, + 2421, -19, -1357, -1018, -21, -357, 162, 140, + -1175, -20, 170, 147, 83, -696, -603, 87, + 1552, 8778, -935, 354, -1424, -147, -4703, -53, + -7, -123, -831, 88, 501, -33, -189, 20, + 134, 763, -81, 30, 4831, -4431, 41, -1479, + -2976, -1424, -1198, 0, -133, -540, 1306, -12, + 11, 436, -400, 3, 877, -804, 7, -268, + 2090, 1192, 1006, 1645, 4853, -266, -86, -61, + -165, -1437, -152, -128, -73, -210, -119, -101, + -619, -353, -298, -487, 2386, 5712, 1426, -94, + 1350, -347, -1991, -124, 0, -111, -832, -207, + -497, 13, 32, 8, -196, -470, -117, 7, + -1349, 1091, 1659, 8891, 313, -111, -72, -168, + -4825, -5, 89, 136, -110, 732, -592, -900, + 25, -20, -31, -170, 9980, 916, -381, -808, + 88, -6080, -51, -8, -39, 0, -558, 232, + 21, 492, 45, -18, -53, -4, 2, 4, + 2338, -1031, -248, 3928, 6484, -333, -64, -3, + -942, -2566, 147, 35, -15, -560, 247, 59, + -925, 408, 98, -1555, 6166, -1240, -337, 3672, + -1277, -2320, -93, -6, -823, -99, 466, 126, + -25, -1382, 278, 75, 480, -96, -26, 286, + 4377, -132, -2588, 1701, 4865, -1169, -1, -409, + -176, -1444, 35, 691, -20, -454, 13, 268, + -1299, 39, 768, -505, 2594, 3295, 3944, 1481, + 682, -410, -662, -949, -133, -28, -521, -624, + -793, -234, -297, -356, -108, -137, -164, -61, + 4151, 624, 815, 4485, 2229, -1052, -23, -40, + -1228, -303, -158, -206, -31, -1136, -170, -223, + -565, -84, -111, -610, -3575, -361, 4924, 2791, + 4698, -780, -7, -1480, -475, -1347, -78, 1074, + 108, 609, 61, -839, 1025, 103, -1412, -800, + -2518, 3791, 8623, 315, 2465, -387, -877, -4538, + -6, -370, 582, 1325, -1995, 48, -73, -166, + 378, -570, -1297, -47, -691, 2989, 9957, -421, + -1142, -29, -545, -6051, -10, -79, 126, 420, + -1817, -17, 76, 256, -48, 208, 694, -29, + -1918, 104, -3190, -3410, -4440, -224, 0, -621, + -709, -1203, 12, -373, 20, -399, 21, -664, + -519, 28, -864, -924, -3359, -1668, 1854, 6939, + 1430, -688, -169, -209, -2939, -124, -341, 380, + 188, 1422, 706, -785, 293, 145, -161, -606, + 42, 9706, 3164, -952, 907, 0, -5750, -611, + -55, -50, -25, -8, -1874, 2, 564, 183, + -2, -537, -175, 52, 1607, 785, 2862, 4327, + 3307, -157, -37, -500, -1143, -667, -77, -280, + -137, -424, -207, -756, -324, -158, -577, -873, + 6801, 3416, 2227, 1682, -3217, -2823, -712, -302, + -172, -631, -1418, -924, -464, -698, -350, -228, + 1335, 670, 437, 330, 3459, 3898, 364, 7841, + -2640, -730, -927, -8, -3753, -425, -823, -76, + -86, -1655, -1865, -174, 557, 628, 58, 1263, + -5902, -3458, -2465, -1886, 4334, -2126, -730, -371, + -217, -1146, -1245, -888, -520, -679, -398, -283, + 1561, 915, 652, 499, -3710, 1133, 7849, 3443, + -215, -840, -78, -3760, -723, -2, 256, 1777, + -543, 779, -238, -1649, -48, 14, 103, 45, + 4132, 2828, 2, -4212, -4116, -1042, -488, 0, + -1083, -1034, -713, 0, 0, 1062, 727, 0, + 1038, 710, 0, -1058, 5875, 8496, -1796, 1376, + -1786, -2107, -4406, -197, -115, -194, -3047, 644, + 931, -493, -713, 150, 640, 926, -195, 150, + 3143, 3483, 3546, -793, 4489, -603, -740, -767, + -38, -1230, -668, -680, -754, 152, 168, 171, + -861, -954, -971, 217, 2845, 7965, 3695, -5432, + 3978, -494, -3873, -833, -1801, -966, -1383, -641, + -1796, 943, 2641, 1225, -691, -1934, -897, 1319, + 1538, 150, 7139, 2049, 3097, -144, -1, -3110, + -256, -585, -14, -670, -65, -192, -18, -892, + -290, -28, -1349, -387, 618, 7520, 4729, -238, + -3373, -23, -3452, -1365, -3, -694, -283, -178, + -2170, 8, 109, 68, 127, 1548, 973, -49, + 2965, -3013, 7912, 7076, -1997, -536, -554, -3821, + -3056, -243, 545, -1431, 1455, -1280, 1301, -3417, + 361, -367, 964, 862, 2443, -929, -1113, 9677, + 4138, -364, -52, -75, -5716, -1045, 138, 166, + -63, -1443, 549, 657, -617, 234, 281, -2444, + 1966, 3309, 10085, -3399, 2105, -236, -668, -6207, + -705, -270, -397, -1210, -2037, 408, 686, 2092, + -252, -425, -1295, 436, -112, -1368, 8868, 4822, + 2048, 0, -114, -4800, -1419, -256, -9, 61, + 740, 33, 402, -2610, 14, 171, -1108, -602, + -2597, 438, -1839, 6229, 7266, -411, -11, -206, + -2368, -3223, 69, -291, 49, 987, -166, 699, + 1152, -194, 816, -2763, 3454, 553, 9127, 4946, + -5596, -728, -18, -5084, -1493, -1911, -116, -1924, + -308, -1042, -166, -2755, 1179, 188, 3117, 1689, + -532, -663, 12262, 2495, -1004, -17, -26, -9177, + -380, -61, -21, 398, 496, 81, 101, -1867, + -32, -40, 751, 152, -2100, 1317, -1509, 11425, + 2997, -269, -105, -139, -7967, -548, 168, -193, + 121, 1464, -918, 1052, 384, -240, 276, -2090, + 1193, -2697, 11259, 5373, -763, -86, -444, -7737, + -1762, -35, 196, -819, 1853, -391, 884, -3692, + 55, -125, 525, 250, 2405, -471, 11079, 203, + 782, -353, -13, -7491, -2, -37, 69, -1626, + 318, -29, 5, -137, -114, 22, -529, -9, + -1871, 5685, 11290, -2662, 1353, -213, -1972, -7780, + -432, -111, 649, 1289, -3917, -304, 923, 1834, + 154, -469, -932, 220, -3768, 5927, -3093, 5041, + 5212, -866, -2144, -584, -1551, -1658, 1363, -711, + 1119, 1159, -1824, 951, 1198, -1885, 984, -1603, + -2546, 9502, 5969, -2440, 1928, -395, -5511, -2175, + -363, -226, 1477, 927, -3462, -379, 1415, 889, + 299, -1118, -702, 287, -4963, 3568, 4592, 5508, + 3451, -1503, -777, -1287, -1851, -727, 1080, 1391, + -1000, 1668, -1199, -1543, 1045, -751, -967, -1160, + 1745, -2586, 3983, 10899, -1551, -186, -408, -968, + -7250, -146, 275, -424, 628, -1161, 1720, -2649, + 165, -244, 377, 1032, 867, -456, -727, 3369, + 11822, -45, -12, -32, -692, -8531, 24, 38, + -20, -178, 93, 149, -625, 329, 525, -2431, + 7535, 2422, 1926, 1405, 1599, -3466, -358, -226, + -120, -156, -1114, -886, -284, -646, -207, -165, + -735, -236, -188, -137, 1041, -735, -142, 13209, + 1515, -66, -33, -1, -10649, -140, 46, 9, + -6, -839, 593, 114, -96, 68, 13, -1222, + 7950, 6745, -1444, -1008, 2721, -3857, -2777, -127, + -62, -452, -3273, 700, 594, 489, 415, -88, + -1320, -1120, 239, 167, -4754, -1379, 4522, -578, + -5733, -1379, -116, -1248, -20, -2006, -400, 1312, + 380, -167, -48, 159, -1663, -482, 1582, -202, + 3220, 5978, 5923, 2430, -2689, -633, -2181, -2141, + -360, -441, -1175, -1164, -2161, -477, -886, -878, + 528, 981, 972, 398, 377, 1312, 13978, -1470, + 677, -8, -105, -11925, -132, -28, -30, -321, + -1119, 33, 117, 1254, -15, -54, -577, 60, + -3435, 6770, 314, -885, 5686, -720, -2797, -6, + -47, -1973, 1419, 65, -129, -185, 366, 16, + 1192, -2349, -109, 307, 3171, 8774, -2260, 2679, + 3069, -613, -4699, -312, -438, -575, -1698, 437, + 1210, -518, -1435, 369, -594, -1643, 423, -501, + 5557, 1509, 5407, -125, -7386, -1884, -139, -1784, + 0, -3330, -511, -1834, -498, 42, 11, 41, + 2505, 680, 2438, -56, -2838, 2595, 13228, 271, + 1793, -491, -411, -10680, -4, -196, 449, 2291, + -2095, 47, -42, -219, 310, -284, -1447, -29, + 664, -278, 14966, 951, -711, -26, -4, -13672, + -55, -30, 11, -606, 253, -38, 16, -869, + 28, -12, 650, 41, 808, 1770, 8658, 5863, + -1486, -39, -191, -4576, -2098, -134, -87, -427, + -935, -289, -633, -3098, 73, 160, 785, 531, + 3063, 1539, 2000, -542, 9576, -572, -144, -244, + -17, -5597, -287, -374, -188, 101, 51, 66, + -1790, -900, -1169, 317, 514, 14083, -323, 896, + -891, -16, -12106, -6, -49, -48, -442, 10, + 277, -28, -770, 17, 27, 766, -17, 48, + 892, 158, 5237, 11057, -1603, -48, -1, -1674, + -7462, -156, -8, -285, -50, -602, -106, -3534, + 87, 15, 512, 1082, -1612, 2564, -4296, 12526, + 5710, -158, -401, -1126, -9576, -1990, 252, -422, + 672, 1232, -1960, 3284, 561, -893, 1497, -4365, + 4889, -6878, 612, 6109, 4753, -1459, -2887, -22, + -2277, -1379, 2052, -182, 257, -1823, 2564, -228, + -1418, 1995, -177, -1772, 3053, -506, 2403, 9625, + 1322, -569, -15, -352, -5655, -106, 94, -448, + 74, -1794, 297, -1412, -246, 40, -194, -777, + -754, 12904, 4480, -2113, 1471, -34, -10163, -1225, + -272, -132, 594, 206, -3529, -97, 1664, 577, + 67, -1159, -402, 189, 4255, 1476, 5055, 2393, + 2912, -1105, -132, -1559, -349, -517, -383, -1313, + -455, -621, -215, -738, -756, -262, -898, -425, + -1371, 535, 1417, 14604, -997, -114, -17, -122, + -13017, -60, 44, 118, -46, 1222, -477, -1263, + -83, 32, 86, 888, 5368, -1744, 4083, -1236, + 3753, -1758, -185, -1017, -93, -860, 571, -1338, + 434, 405, -131, 308, -1229, 399, -935, 283, + 1588, -3097, 14415, 3699, -1171, -154, -585, -12683, + -835, -83, 300, -1397, 2725, -358, 699, -3255, + 113, -221, 1030, 264, 212, 7989, 9471, -3344, + 2009, -2, -3895, -5475, -682, -246, -103, -123, + -4618, 43, 1630, 1933, -26, -979, -1161, 410, + 856, 2294, -627, 6930, 6929, -44, -321, -24, + -2931, -2930, -119, 32, 87, -362, -970, 265, + -362, -970, 265, -2931, 2357, -4187, 7162, 7683, + 3371, -339, -1070, -3131, -3603, -693, 602, -1030, + 1830, -1105, 1963, -3359, -485, 861, -1474, -1581, + 350, 4585, 14053, -3819, 1218, -7, -1283, -12054, + -890, -90, -97, -300, -3933, 81, 1068, 3275, + -26, -341, -1045, 284, -3248, 3531, 475, 2137, + 11711, -644, -761, -13, -278, -8372, 700, 94, + -102, 423, -460, -62, 2322, -2524, -340, -1528, + -3017, 3852, 1725, 8440, 5257, -555, -905, -181, + -4348, -1686, 709, 317, -405, 1554, -1984, -889, + 968, -1236, -553, -2708, -909, 3196, 15512, -2528, + 1066, -50, -623, -14686, -390, -69, 177, 861, + -3026, -140, 493, 2393, 59, -208, -1009, 164, + 959, -3370, 9617, 9545, -1761, -56, -693, -5645, + -5561, -189, 197, -563, 1978, -558, 1963, -5603, + 103, -362, 1034, 1026, 7575, 11796, -4845, 3252, + -1703, -3502, -8493, -1433, -645, -177, -5454, 2240, + 3488, -1503, -2341, 961, 787, 1226, -503, 338, + 6409, 1722, 1764, -4191, 6015, -2507, -181, -189, + -1072, -2208, -673, -690, -185, 1639, 440, 451, + -2353, -632, -647, 1538, -2420, 12161, 5038, 1286, + -2098, -357, -9027, -1549, -100, -268, 1796, 744, + -3740, 190, -954, -395, -310, 1557, 645, 164, + -2232, -1341, 7246, 9470, -1977, -304, -109, -3204, + -5474, -238, -182, 987, 593, 1290, 775, -4188, + -269, -161, 874, 1143, 1030, 7034, 4231, 1551, + 3077, -64, -3019, -1093, -146, -577, -442, -266, + -1816, -97, -666, -400, -193, -1321, -794, -291, + 5121, 11835, -477, -1749, 2298, -1601, -8549, -13, + -186, -322, -3699, 149, 344, 546, 1264, -50, + -718, -1660, 66, 245, -3328, 3827, 5921, 9976, + -1045, -676, -894, -2140, -6075, -66, 777, 1203, + -1383, 2027, -2330, -3605, -212, 244, 377, 636, + 3813, 5718, -4666, -3412, 5674, -887, -1995, -1329, + -710, -1965, -1331, 1086, 1628, 794, 1191, -972, + -1320, -1980, 1616, 1181, 1348, -3672, 13154, 6938, + -1690, -110, -823, -10561, -2938, -174, 302, -1082, + 2948, -570, 1555, -5570, 139, -379, 1357, 716, + 2151, -3586, 6949, 12131, -1224, -282, -785, -2947, + -8982, -91, 470, -912, 1521, -1592, 2655, -5145, + 160, -268, 519, 906, -2889, 9647, 10276, -2728, + 995, -509, -5680, -6445, -454, -60, 1701, 1812, + -6051, -481, 1606, 1711, 175, -586, -624, 165, + 6177, 2184, 555, 1985, 6589, -2329, -291, -18, + -240, -2650, -823, -209, -74, -748, -264, -67, + -2484, -878, -223, -798, -492, 391, 17166, -681, + 240, -14, -9, -17987, -28, -3, 11, 515, + -410, -20, 16, 713, 7, -5, -252, 10, + 12628, 5448, -2630, 3011, -2695, -9733, -1811, -422, + -553, -443, -4199, 2027, 874, -2321, -1001, 483, + 2077, 896, -432, 495, -3628, -534, 3447, 7002, + 6751, -803, -17, -725, -2992, -2782, -118, 763, + 112, 1550, 228, -1473, 1495, 220, -1420, -2885, + -5239, 5901, 8107, 3650, 4846, -1675, -2125, -4012, + -813, -1433, 1887, 2592, -2920, 1167, -1315, -1806, + 1550, -1745, -2398, -1080, 6157, 6678, 4099, -1074, + 2348, -2314, -2722, -1025, -70, -336, -2509, -1540, + -1670, 403, 437, 268, -882, -957, -587, 153, + 1079, 16099, 242, -881, 1690, -71, -15820, -3, + -47, -174, -1060, -16, -238, 58, 865, 13, + -111, -1661, -25, 90, -278, 227, -1039, 1636, + 16945, -4, -3, -65, -163, -17526, 3, -17, + 14, 27, -22, 103, 287, -234, 1074, -1693, + 15778, -1454, 574, -603, -107, -15195, -129, -20, + -22, 0, 1400, -553, 51, 581, -53, 21, + 103, -9, 3, -3, 2406, -836, 13224, 7993, + -4266, -353, -42, -10673, -3899, -1111, 122, -1942, + 674, -1174, 407, -6451, 626, -217, 3443, 2081, + 3184, 14368, -3336, 2255, -1801, -619, -12600, -679, + -310, -198, -2793, 648, 2926, -438, -1977, 459, + 350, 1580, -366, 247, -1698, 17076, 2504, -539, + -646, -176, -17798, -382, -17, -25, 1770, 259, + -2610, -55, 561, 82, -67, 673, 98, -21, + 2375, -797, -2696, 14483, 5383, -344, -38, -443, + -12803, -1769, 115, 391, -131, -2100, 705, 2384, + -780, 262, 886, -4759, -2691, 2554, -4520, 9573, + 10655, -442, -398, -1247, -5594, -6930, 419, -742, + 704, 1572, -1492, 2641, 1750, -1661, 2939, -6226, + -4332, -4399, -1657, 4880, 7375, -1145, -1181, -167, + -1453, -3319, -1163, -438, -444, 1290, 1310, 493, + 1950, 1980, 745, -2196, -3498, 7405, 9955, 2693, + -2971, -746, -3347, -6049, -442, -538, 1581, 2125, + -4499, 575, -1217, -1636, -634, 1342, 1805, 488, + 6717, -3792, 7739, 2798, 3489, -2754, -877, -3655, + -477, -743, 1554, -3173, 1791, -1147, 647, -1321, + -1430, 807, -1648, -595, 5263, 9770, 3463, 1069, + -3971, -1690, -5826, -732, -69, -962, -3138, -1112, + -2065, -343, -637, -226, 1275, 2368, 839, 259, + 1243, -2634, 16772, 1871, 332, -94, -423, -17169, + -213, -6, 199, -1273, 2696, -142, 300, -1915, + -25, 53, -339, -37, 2691, 2836, 3105, 5711, + 4817, -442, -491, -588, -1991, -1416, -465, -510, + -537, -938, -988, -1082, -791, -834, -913, -1679, + 4366, 2944, 7210, 3627, 1161, -1163, -529, -3172, + -803, -82, -784, -1921, -1295, -966, -651, -1596, + -309, -208, -511, -257, 13888, 3951, -671, -2305, + 3354, -11773, -953, -27, -324, -686, -3349, 569, + 161, 1954, 556, -94, -2843, -809, 137, 472, + 7053, 5847, 2929, 8378, -4794, -3036, -2086, -523, + -4284, -1403, -2517, -1261, -1045, -3607, -2990, -1498, + 2064, 1711, 857, 2451, -2191, 12838, 9182, -3915, + 1617, -293, -10059, -5146, -935, -159, 1717, 1228, + -7195, -523, 3068, 2194, 216, -1267, -906, 386, + -4881, 13114, 5767, -435, 4155, -1454, -10498, -2030, + -11, -1054, 3907, 1718, -4616, -129, 348, 153, + 1238, -3326, -1462, 110, 7843, -1250, 210, 7106, + -5203, -3754, -95, -2, -3082, -1652, 598, -100, + 16, -3402, 542, -91, 2491, -397, 66, 2257, + -2463, 8168, 14551, -3908, 1828, -370, -4072, -12923, + -932, -204, 1228, 2188, -7254, -587, 1948, 3471, + 274, -911, -1623, 436, -1579, 347, -272, -2735, + 16031, -152, -7, -4, -456, -15686, 33, -26, + 5, -263, 58, -45, 1545, -340, 266, 2676, + -6327, 1328, 5093, -5079, 7617, -2443, -107, -1583, + -1574, -3541, 513, 1967, -413, -1961, 411, 1578, + 2941, -617, -2367, 2361, 3286, -4509, 11306, 11025, + -2623, -659, -1241, -7802, -7419, -420, 904, -2267, + 3112, -2211, 3034, -7608, 526, -722, 1810, 1765, + 5567, 17853, -3754, 1166, -519, -1892, -19455, -860, + -83, -16, -6067, 1275, 4090, -396, -1271, 267, + 176, 566, -119, 37, -2136, -424, 15292, 5108, + -1648, -278, -10, -14273, -1593, -165, -55, 1993, + 396, 666, 132, -4768, -214, -42, 1538, 514, + 2267, -3297, 2549, 16563, -791, -313, -663, -396, + -16745, -38, 456, -352, 513, -2291, 3333, -2576, + 109, -159, 123, 799, 3655, 1899, -3364, 6279, + 12510, -815, -220, -690, -2406, -9552, -423, 750, + 390, -1400, -728, 1289, -2791, -1450, 2568, -4794, + 8052, 2285, -6193, 5138, 6003, -3957, -318, -2341, + -1611, -2199, -1123, 3044, 864, -2525, -716, 1942, + -2950, -837, 2269, -1882, -386, -2291, 7679, 15387, + -2723, -9, -320, -3599, -14452, -452, -54, 181, + 1074, 362, 2152, -7212, -64, -380, 1276, 2557, + 2777, -1173, 3984, 13079, 2508, -470, -84, -969, + -10440, -384, 198, -675, 285, -2217, 936, -3180, + -425, 179, -610, -2002, -1879, 1771, -2684, 16705, + 1833, -215, -191, -439, -17032, -205, 203, -308, + 290, 1916, -1805, 2736, 210, -198, 300, -1869, + 1052, 4495, 15519, 1467, -4032, -67, -1233, -14700, + -131, -992, -288, -997, -4257, -94, -402, -1389, + 259, 1106, 3819, 361, 3010, 2544, 6969, 7559, + 1996, -553, -395, -2964, -3487, -243, -467, -1280, + -1082, -1388, -1174, -3215, -366, -310, -849, -921, + -5209, -1867, 8713, 10351, 1549, -1656, -212, -4634, + -6540, -146, -593, 2770, 993, 3291, 1180, -5505, + 492, 176, -824, -979, -4314, 8513, 913, 7547, + -2723, -1135, -4423, -50, -3476, -452, 2241, 240, + -474, 1987, -3921, -420, -717, 1415, 151, 1254, + 12929, -1219, 2448, 1757, 6303, -10204, -90, -365, + -188, -2425, 962, -1932, 182, -1386, 130, -262, + -4974, 469, -941, -676, 6465, 4132, 3167, 3160, + 5697, -2551, -1042, -612, -609, -1981, -1630, -1249, + -798, -1247, -797, -611, -2248, -1437, -1101, -1099, + -3636, 4859, 18914, -1335, 810, -807, -1441, -21836, + -108, -40, 1078, 4198, -5609, -296, 396, 1541, + 179, -240, -936, 66, 8844, 7864, 654, -4063, + -5680, -4774, -3774, -26, -1007, -1969, -4245, -353, + -314, 2193, 1950, 162, 3066, 2726, 226, -1408, + 1859, 2634, 9228, 996, 9464, -211, -423, -5197, + -60, -5467, -299, -1047, -1483, -113, -160, -561, + -1074, -1521, -5330, -575, 2949, 12260, 10290, -497, + -3943, -530, -9174, -6463, -15, -949, -2206, -1852, + -7700, 89, 372, 312, 709, 2950, 2476, -119, + -2903, 1552, 14867, 9970, -496, -514, -147, -13491, + -6068, -15, 275, 2634, -1408, 1766, -944, -9047, + -87, 47, 450, 302, 3243, 8234, 7586, 3373, + 2151, -642, -4138, -3512, -694, -282, -1630, -1501, + -3812, -667, -1695, -1561, -425, -1081, -996, -442, + -9631, 60, 3501, 5359, 10150, -5662, 0, -748, + -1752, -6288, 35, 2058, -12, 3150, -19, -1145, + 5967, -37, -2169, -3320, -6874, -2553, -5446, -2195, + -7841, -2884, -397, -1810, -294, -3753, -1071, -2285, + -848, -921, -342, -729, -3290, -1221, -2606, -1050, + -3413, -1141, 4630, 13612, 7897, -711, -79, -1308, + -11310, -3806, -237, 964, 322, 2836, 948, -3847, + 1645, 550, -2231, -6561, 4410, -5678, 8006, -3992, + 3811, -1187, -1968, -3912, -973, -886, 1528, -2155, + 2775, 1074, -1383, 1951, -1025, 1321, -1862, 928, + 5659, 11535, 2203, -452, 7169, -1954, -8121, -296, + -12, -3137, -3984, -761, -1551, 156, 318, 60, + -2476, -5048, -964, 197, 2914, -2914, 3485, -3965, + 13675, -518, -518, -741, -959, -11414, 518, -620, + 620, 705, -705, 843, -2433, 2432, -2909, 3310, + 7843, 1907, 1022, 8882, 7972, -3755, -222, -63, + -4815, -3879, -913, -489, -119, -4252, -1034, -554, + -3816, -928, -497, -4322, 13807, 9531, 1436, 1612, + 1779, -11636, -5544, -125, -158, -193, -8032, -1210, + -835, -1358, -938, -141, -1499, -1035, -156, -175, + 13620, -5337, 5450, -2263, 1723, -11322, -1738, -1813, + -312, -181, 4436, -4531, 1775, 1881, -737, 752, + -1432, 561, -573, 238, 5297, 8374, 8872, 7694, + 6538, -1712, -4280, -4804, -3613, -2609, -2707, -2868, + -4534, -2487, -3932, -4166, -2113, -3341, -3540, -3070 +}; + +/* +** AcbkGainTablePtr: +** +** Purpose: +** Contains pointers to 85 and 170 element codebooks +** +*/ + +Word16 *AcbkGainTablePtr[2] = { + AcbkGainTable085, + AcbkGainTable170, +}; + + +/* +** LpfConstTable: +** +** Purpose: +** Sets the postfilter gain weighting factor. +** +** Table Structure: +** (0.1875 , 0.25) in Q15 ( i.e. scale by 32768 ). + +*/ + +Word16 LpfConstTable[2] = { + 0x1800, + 0x2000, +}; + + +/* +** epsi170: +** +** Purpose: +** At the lower bitrate, the pitch contribution is added +** into the output vector of ACELP when the pitch period is +** less than 60 samples (one subframe). The pitch contribution +** is estimated by a 1 tap long term predictor (LTP) instead of +** the 5 tap LTP used in pitch prediction. The values in epsi170 +** effectively choose one of the 5 vectors used in the 5 tap LTP. +** +** Table Structure: +** The table is indexed by the index into the AcbkGainTable170 +** table (determined in Find_Acbk). The value, 60, is used only +** as a place holder. They correspond to zeros in the gain170 +** table, which is the coefficient of the 1 tap long term +** predictor (LTP). The rest of the values range from -2 to +2. +** These values pick one vector among the 5 vectors centered one +** pitch period behind the current vector. (In contrast, the 5 +** tap LTP uses all five vectors centered one pitch period back.) +*/ +Word16 epsi170[170] = { + 60, 0, 60, 0, 1, 0, 0, 1, + -1, 1, 0, -1, 2, -2, 0, 1, + 0, 0, -1, 0, 0, 0, 1, 0, + -1, -1, 1, -1, 1, -2, 1, -1, + 60, 0, 0, 1, 1, 0, 1, 1, + -1, 1, -1, -1, -1, 0, 60, -2, + 0, 1, 0, -1, 1, 1, 0, 1, + 2, -1, 0, 1, 0, 0, 0, 60, + -1, 1, 1, 2, -1, 1, -1, 60, + -1, 0, 1, 0, -1, 0, 0, 0, + 1, -1, 0, 1, -1, 0, -1, 0, + 1, 60, 0, 0, 1, 1, 0, 2, + 1, 0, 1, -2, 0, -1, 1, 0, + -1, 1, 0, 0, 1, 0, 0, 0, + 60, 1, 1, -1, -1, 2, -2, 0, + -1, -1, 60, 2, 60, 0, 0, 60, + 0, 0, 0, -2, 60, -1, 0, 60, + 0, 2, 0, 0, -1, 0, 1, 2, + 60, 1, 1, 1, 0, 0, 60, 0, + 60, 0, 0, 60, 60, -1, 0, 0, + 60, 60, 1, 0, 60, 2, 60, -2, + -2, 0 +}; + +/* +** gain170: +** +** Purpose: +** At the lower bitrate, the pitch contribution is added into +** the output vector of ACELP when the pitch period is less than +** 60 samples (one subframe). The pitch contribution +** is estimated by a 1 tap long term predictor (LTP) instead of +** the 5 tap LTP used in pitch prediction. This table holds the +** coefficient for the one tap filter. +** +** Table Structure: +** The table is indexed by the index into the AcbkGainTable170 +** table (determined in Find_Acbk). The values are in Q12. +*/ + +Word16 gain170[170] = { + 0, 2489, 0, 5217, 6171, 3953, 10364, 9357, + 8843, 9396, 5794, 10816, 11606, 12072, 8616, 12170, + 14440, 7787, 13721, 18205, 14471, 15807, 15275, 13480, + 18375, 0, 11194, 13010, 18836, 20354, 16233, 0, + 0, 12130, 13385, 17834, 20875, 21996, 0, 18277, + 21321, 13738, 19094, 20387, 0, 21008, 0, 22807, + 15900, 0, 17989, 22259, 24395, 23138, 23948, 22997, + 22604, 25942, 26246, 25321, 26423, 24061, 27247, 0, + 25572, 23918, 25930, 26408, 19049, 27357, 24538, 0, + 25093, 28549, 0, 22793, 25659, 29377, 30276, 26198, + 22521, 28919, 27384, 30162, 0, 24237, 30062, 21763, + 30917, 0, 31284, 29433, 26821, 28655, 31327, 30799, + 31389, 32322, 31760, 31830, 26936, 31180, 30875, 27873, + 30429, 31050, 0, 31912, 31611, 31565, 25557, 31357, + 0, 29536, 28985, 26984, 31587, 30836, 31133, 30243, + 30742, 32090, 0, 30902, 0, 30027, 29042, 0, + 31756, 24553, 25636, 30501, 0, 29617, 30649, 0, + 29274, 30415, 27480, 31213, 28147, 30600, 31652, 29068, + 0, 28571, 28730, 31422, 28257, 24797, 0, 0, + 0, 22105, 27852, 0, 0, 24214, 24642, 23305, + 0, 0, 22883, 21601, 0, 25650, 0, 31253, + 25144, 17998 +}; + +/* +** tabgain170: +** +** Purpose: +** In the taming procedure at the encoder the 170 5-taps LT filters +** are modelled as 1-tap filter. This table gives the gain +** value attributed to each filter as a worst case gain +** +** Table Structure: +** The table is indexed by the index into the AcbkGainTable170 +** table (determined in Find_Acbk). The values are in Q13. +*/ +Word16 tabgain170[170] = { + 1024, 1591, 1678, 1891, 2120, 2399, 2966, 3049, + 3185, 3317, 3433, 3523, 3729, 3779, 3789, 4262, + 4450, 4469, 4713, 4944, 4950, 4980, 5010, 5032, + 5299, 5389, 5389, 5389, 5646, 5701, 5733, 5765, + 5997, 5997, 6150, 6211, 6336, 6360, 6415, 6415, + 6430, 6440, 6461, 6461, 6512, 6601, 6787, 6872, + 6931, 6972, 6984, 7056, 7056, 7105, 7117, 7123, + 7136, 7161, 7167, 7180, 7180, 7262, 7308, 7334, + 7334, 7387, 7407, 7434, 7441, 7441, 7481, 7536, + 7564, 7592, 7685, 7714, 7758, 7772, 7794, 7802, + 7817, 7839, 7869, 7885, 7907, 7946, 7992, 8039, + 8063, 8087, 8087, 8167, 8184, 8200, 8200, 8241, + 8266, 8283, 8308, 8308, 8334, 8376, 8402, 8463, + 8516, 8524, 8533, 8641, 8669, 8696, 8752, 8761, + 8799, 8828, 8943, 9112, 9122, 9133, 9153, 9288, + 9299, 9373, 9384, 9384, 9405, 9416, 9471, 9503, + 9559, 9581, 9660, 9660, 9718, 9799, 9823, 9846, + 9846, 9930, 10039, 10164, 10227, 10291, 10436, 10503, + 10516, 10530, 10598, 10611, 10625, 11040, 11070, 11100, + 11115, 11315, 11331, 11804, 12100, 12263, 12263, 12300, + 12337, 12431, 12800, 12962, 13065, 13496, 13815, 14100, + 14198, 18409 +}; + +/* +** tabgain85: +** +** Purpose: +** In the taming procedure at the encoder the 85 5-taps LT filters +** are modelled as 1-tap filter. This table gives the gain +** value attributed to each filter as a worst case gain +** +** Table Structure: +** The table is indexed by the index into the AcbkGainTable085 +** table (determined in Find_Acbk). The values are in Q13. +*/ +Word16 tabgain85[85] = { + 1024, 1308, 1906, 2291, 2511, 2736, 3298, 3489, + 3531, 3844, 4360, 4541, 4684, 4813, 5069, 5528, + 5577, 5713, 5923, 5958, 5958, 6064, 6132, 6331, + 6370, 6527, 6533, 6575, 6633, 6671, 6832, 6832, + 6972, 6996, 7199, 7205, 7414, 7529, 7543, 7543, + 7692, 7758, 7839, 7839, 7869, 7992, 8000, 8016, + 8055, 8079, 8119, 8208, 8250, 8266, 8291, 8300, + 8325, 8402, 8445, 8605, 8623, 8687, 8752, 8837, + 8847, 8973, 9002, 9012, 9184, 9593, 9672, 9752, + 9846, 9978, 10139, 10202, 10317, 10476, 10598, 10598, + 10695, 11425, 11670, 14629, 15255 +}; + +/* +** fact : +** L_bseg : +** base : +** +** Purpose: +** Quantization of the SID gain procedure +** table fact : +** for n = 0 : used to quantize the excitation energy estimation +** in Comp_Info() +** fact(0) = 32768 / (2 * SubFrLen) +** +** for n >= 1 : used for average energy calculation +** fact(n) = fact_mul**2 * 32768 / n * Frame +** table L_bseg : for each segment of the pseudo-log quantizer, +** gives the energy level corresponding to +** the first value of the next segment +** table base : first code of each segment +** +*/ +Word16 fact[4] = { 273, 998, 499, 333 }; +Word32 L_bseg[3] = { 2048L, 18432L, 231233L }; /* Bug fixed 24-09-96 */ +Word16 base[3] = { 0, 32, 96 }; diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/tab_lbc.h asterisk-1.2.1/codecs/g723_1/tab_lbc.h --- asterisk-1.2.1.ori/codecs/g723_1/tab_lbc.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/tab_lbc.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,40 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "tab_lbc.h" +** +** Description: This file contains extern declarations of the tables used +** by the SG15 LBC Coder for 6.3/5.3 kbps. +*/ + +extern Word16 HammingWindowTable[LpcFrame]; +extern Word16 BinomialWindowTable[LpcOrder]; +extern Word16 BandExpTable[LpcOrder]; +extern Word16 CosineTable[CosineTableSize]; +extern Word16 LspDcTable[LpcOrder]; +extern Word16 BandInfoTable[LspQntBands][2]; +extern Word16 Band0Tb8[LspCbSize * 3]; +extern Word16 Band1Tb8[LspCbSize * 3]; +extern Word16 Band2Tb8[LspCbSize * 4]; +extern Word16 *BandQntTable[LspQntBands]; +extern Word16 PerFiltZeroTable[LpcOrder]; +extern Word16 PerFiltPoleTable[LpcOrder]; +extern Word16 PostFiltZeroTable[LpcOrder]; +extern Word16 PostFiltPoleTable[LpcOrder]; +extern Word16 Nb_puls[4]; +extern Word16 FcbkGainTable[NumOfGainLev]; +extern Word32 MaxPosTable[4]; +extern Word32 CombinatorialTable[MaxPulseNum][SubFrLen / Sgrid]; +extern Word16 AcbkGainTable085[85 * 20]; +extern Word16 AcbkGainTable170[170 * 20]; +extern Word16 *AcbkGainTablePtr[2]; +extern Word16 LpfConstTable[2]; +extern Word16 epsi170[170]; +extern Word16 gain170[170]; +extern Word16 tabgain170[170]; +extern Word16 tabgain85[85]; +extern Word16 fact[4]; +extern Word32 L_bseg[3]; +extern Word16 base[3]; diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/tame.c asterisk-1.2.1/codecs/g723_1/tame.c --- asterisk-1.2.1.ori/codecs/g723_1/tame.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/tame.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,206 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +*/ + +/* +** +** File: tame.c +** +** Description: Functions used to avoid possible explosion of the decoder +** excitation in case of series of long term unstable filters +** and when the encoder and the decoder are de-synchronized +** +** Functions: +** +** Computing excitation error estimation : +** Update_Err() +** Test excitation error : +** Test_Err() +*/ + +#include +#include + +#include "typedef.h" +#include "basop.h" +#include "cst_lbc.h" +#include "coder.h" +#include "exc_lbc.h" +#include "tame.h" +#include "tab_lbc.h" + + +/* +** +** Function: Update_Err() +** +** Description: Estimation of the excitation error associated +** to the excitation signal when it is disturbed at +** the decoder, the disturbing signal being filtered +** by the long term synthesis filters +** one value for (SubFrLen/2) samples +** Updates the table CodStat->Err +** +** Links to text: Section +** +** Arguments: +** +** Word16 Olp Center value for pitch delay +** Word16 AcLg Offset value for pitch delay +** Word16 AcGn Index of Gain LT filter +** +** Outputs: None +** +** Return value: None +** +*/ + +void +Update_Err (CODSTATDEF * CodStat, Word16 Olp, Word16 AcLg, Word16 AcGn) +{ + Word16 *ptr_tab; + Word16 i, iz, temp1, temp2; + Word16 Lag; + Word32 Worst1, Worst0, L_temp; + Word16 beta; + + Lag = Olp - (Word16) Pstep + AcLg; + + /* Select Quantization tables */ + i = 0; + ptr_tab = tabgain85; + if (CodStat->WrkRate == Rate63) { + if (Olp >= (Word16) (SubFrLen - 2)) + ptr_tab = tabgain170; + } + else { + ptr_tab = tabgain170; + } + beta = ptr_tab[(int) AcGn]; /* beta = gain * 8192 */ + + + if (Lag <= (SubFrLen / 2)) { + Worst0 = L_mls (CodStat->Err[0], beta); + Worst0 = L_shl (Worst0, 2); + Worst0 = L_add (Err0, Worst0); + Worst1 = Worst0; + } + + else { + iz = mult (Lag, 1092); /* Lag / 30 */ + temp1 = add (iz, 1); + temp2 = sub (shl (temp1, 5), shl (temp1, 1)); /* 30 (iz+1) */ + if (temp2 != Lag) { + + if (iz == 1) { + Worst0 = L_mls (CodStat->Err[0], beta); + Worst0 = L_shl (Worst0, 2); + Worst0 = L_add (Err0, Worst0); + Worst1 = L_mls (CodStat->Err[1], beta); + Worst1 = L_shl (Worst1, 2); + Worst1 = L_add (Err0, Worst1); + if (Worst0 > Worst1) + Worst1 = Worst0; + else + Worst0 = Worst1; + } + + else { + Worst0 = L_mls (CodStat->Err[iz - 2], beta); + Worst0 = L_shl (Worst0, 2); + Worst0 = L_add (Err0, Worst0); + L_temp = L_mls (CodStat->Err[iz - 1], beta); + L_temp = L_shl (L_temp, 2); + L_temp = L_add (Err0, L_temp); + if (L_temp > Worst0) + Worst0 = L_temp; + Worst1 = L_mls (CodStat->Err[iz], beta); + Worst1 = L_shl (Worst1, 2); + Worst1 = L_add (Err0, Worst1); + if (L_temp > Worst1) + Worst1 = L_temp; + } + } + else { /* Lag % SubFrLen = 0 */ + Worst0 = L_mls (CodStat->Err[iz - 1], beta); + Worst0 = L_shl (Worst0, 2); + Worst0 = L_add (Err0, Worst0); + Worst1 = L_mls (CodStat->Err[iz], beta); + Worst1 = L_shl (Worst1, 2); + Worst1 = L_add (Err0, Worst1); + } + } + + for (i = 4; i >= 2; i--) { + CodStat->Err[i] = CodStat->Err[i - 2]; + } + CodStat->Err[0] = Worst0; + CodStat->Err[1] = Worst1; + + return; +} + +/* +** +** Function: Test_Err() +** +** Description: Check the error excitation maximum for +** the subframe and computes an index iTest used to +** calculate the maximum nb of filters (in Find_Acbk) : +** Bound = Min(Nmin + iTest x pas, Nmax) , with +** AcbkGainTable085 : pas = 2, Nmin = 51, Nmax = 85 +** AcbkGainTable170 : pas = 4, Nmin = 93, Nmax = 170 +** iTest depends on the relative difference between +** errmax and a fixed threshold +** +** Links to text: Section +** +** Arguments: +** +** Word16 Lag1 1st long term Lag of the tested zone +** Word16 Lag2 2nd long term Lag of the tested zone +** +** Outputs: None +** +** Return value: +** Word16 index iTest used to compute Acbk number of filters +*/ + +Word16 +Test_Err (CODSTATDEF * CodStat, Word16 Lag1, Word16 Lag2) +{ + + int i, i1, i2; + Word16 zone1, zone2; + Word32 Acc, Err_max; + Word16 iTest; + + i2 = Lag2 + ClPitchOrd / 2; + zone2 = mult ((Word16) i2, (Word16) 1092); + + i1 = -SubFrLen + 1 + Lag1 - ClPitchOrd / 2; + if (i1 <= 0) + i1 = 1; + zone1 = mult ((Word16) i1, (Word16) 1092); + + Err_max = -1L; + for (i = zone2; i >= zone1; i--) { + Acc = L_sub (CodStat->Err[i], Err_max); + if (Acc > 0L) { + Err_max = CodStat->Err[i]; + } + } + Acc = L_sub (Err_max, ThreshErr); + if ((Acc > 0L) || (CodStat->SinDet < 0)) { + iTest = 0; + } + else { + Acc = L_negate (Acc); + Acc = L_shr (Acc, DEC); + iTest = extract_l (Acc); + } + + return (iTest); +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/tame.h asterisk-1.2.1/codecs/g723_1/tame.h --- asterisk-1.2.1.ori/codecs/g723_1/tame.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/tame.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,10 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +*/ + +#include "coder.h" + +void Update_Err (CODSTATDEF * CodStat, Word16 Olp, Word16 AcLg, Word16 AcGn); +Word16 Test_Err (CODSTATDEF * CodStat, Word16 Lag1, Word16 Lag2); diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/typedef.h asterisk-1.2.1/codecs/g723_1/typedef.h --- asterisk-1.2.1.ori/codecs/g723_1/typedef.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/typedef.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,13 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +*/ + +/* +** Types definitions +*/ + +typedef short Word16; +typedef int Word32; +typedef int Flag; diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/util_cng.c asterisk-1.2.1/codecs/g723_1/util_cng.c --- asterisk-1.2.1.ori/codecs/g723_1/util_cng.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/util_cng.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,434 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +*/ +/* +** +** File: "util_cng.c" +** +** Description: General Comfort Noise Generation functions +** +** +** Functions: Calc_Exc_Rand() Computes random excitation +** used both by coder & decoder +** Qua_SidGain() Quantization of SID gain +** used by coder +** Dec_SidGain() Decoding of SID gain +** used both by coder & decoder +** +** Local functions : +** distG() +** random_number() + +*/ + +#include +#include + +#include "typedef.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "util_lbc.h" +#include "exc_lbc.h" +#include "basop.h" +#include "util_cng.h" + +/* Declaration of local functions */ +static Word16 random_number (Word16 number_max_p1, Word16 * nRandom); + +/* +** +** Function: Calc_Exc_Rand() +** +** Description: Computation of random excitation for inactive frames: +** Adaptive codebook entry selected randomly +** Higher rate innovation pattern selected randomly +** Computes innovation gain to match curGain +** +** Links to text: +** +** Arguments: +** +** Word16 curGain current average gain to match +** Word16 *PrevExc previous/current excitation (updated) +** Word16 *DataEXc current frame excitation +** Word16 *nRandom random generator status (input/output) +** +** Outputs: +** +** Word16 *PrevExc +** Word16 *DataExc +** Word16 *nRandom +** +** Return value: None +** +*/ +void +Calc_Exc_Rand (enum Crate WrkRate, Word16 curGain, Word16 * PrevExc, + Word16 * DataExc, Word16 * nRandom, LINEDEF * Line) +{ + int i, i_subfr, iblk; + Word16 temp, temp2; + Word16 j; + Word16 TabPos[2 * NbPulsBlk], TabSign[2 * NbPulsBlk]; + Word16 *ptr_TabPos, *ptr_TabSign; + Word16 *ptr1, *curExc; + Word16 sh1, x1, x2, inter_exc, delta, b0; + Word32 L_acc, L_c, L_temp; + Word16 tmp[SubFrLen / Sgrid]; + Word16 offset[SubFrames]; + Word16 tempExc[SubFrLenD]; + + /* + * generate LTP codes + */ + Line->Olp[0] = random_number (21, nRandom) + (Word16) 123; + Line->Olp[1] = random_number (21, nRandom) + (Word16) 123; + for (i_subfr = 0; i_subfr < SubFrames; i_subfr++) { /* in [1, NbFilt] */ + Line->Sfs[i_subfr].AcGn = random_number (NbFilt, nRandom) + (Word16) 1; + } + Line->Sfs[0].AcLg = 1; + Line->Sfs[1].AcLg = 0; + Line->Sfs[2].AcLg = 1; + Line->Sfs[3].AcLg = 3; + + + /* + * Random innovation : + * Selection of the grids, signs and pulse positions + */ + + /* Signs and Grids */ + ptr_TabSign = TabSign; + ptr1 = offset; + for (iblk = 0; iblk < SubFrames / 2; iblk++) { + temp = random_number ((1 << (NbPulsBlk + 2)), nRandom); + *ptr1++ = temp & (Word16) 0x0001; + temp = shr (temp, 1); + *ptr1++ = add ((Word16) SubFrLen, (Word16) (temp & 0x0001)); + for (i = 0; i < NbPulsBlk; i++) { + *ptr_TabSign++ = shl (sub ((temp & (Word16) 0x0002), 1), 14); + temp = shr (temp, 1); + } + } + + /* Positions */ + ptr_TabPos = TabPos; + for (i_subfr = 0; i_subfr < SubFrames; i_subfr++) { + + for (i = 0; i < (SubFrLen / Sgrid); i++) + tmp[i] = (Word16) i; + temp = (SubFrLen / Sgrid); + for (i = 0; i < Nb_puls[i_subfr]; i++) { + j = random_number (temp, nRandom); + *ptr_TabPos++ = add (shl (tmp[(int) j], 1), offset[i_subfr]); + temp = sub (temp, 1); + tmp[(int) j] = tmp[(int) temp]; + } + } + + /* + * Compute fixed codebook gains + */ + + ptr_TabPos = TabPos; + ptr_TabSign = TabSign; + curExc = DataExc; + i_subfr = 0; + for (iblk = 0; iblk < SubFrames / 2; iblk++) { + + /* decode LTP only */ + Decod_Acbk (WrkRate, curExc, &PrevExc[0], Line->Olp[iblk], + Line->Sfs[i_subfr].AcLg, Line->Sfs[i_subfr].AcGn); + Decod_Acbk (WrkRate, &curExc[SubFrLen], &PrevExc[SubFrLen], + Line->Olp[iblk], Line->Sfs[i_subfr + 1].AcLg, + Line->Sfs[i_subfr + 1].AcGn); + + temp2 = 0; + for (i = 0; i < SubFrLenD; i++) { + temp = abs_s (curExc[i]); + if (temp > temp2) + temp2 = temp; + } + if (temp2 == 0) + sh1 = 0; + else { + sh1 = sub (4, norm_s (temp2)); /* 4 bits of margin */ + if (sh1 < -2) + sh1 = -2; + } + + L_temp = 0L; + for (i = 0; i < SubFrLenD; i++) { + temp = shr (curExc[i], sh1); /* left if sh1 < 0 */ + L_temp = L_mac (L_temp, temp, temp); + tempExc[i] = temp; + } /* ener_ltp x 2**(-2sh1+1) */ + + L_acc = 0L; + for (i = 0; i < NbPulsBlk; i++) { + L_acc = L_mac (L_acc, tempExc[(int) ptr_TabPos[i]], ptr_TabSign[i]); + } + inter_exc = extract_h (L_shl (L_acc, 1)); /* inter_exc x 2-sh1 */ + + /* compute SubFrLenD x curGain**2 x 2**(-2sh1+1) */ + /* curGain input = 2**5 curGain */ + L_acc = L_mult (curGain, SubFrLen); + L_acc = L_shr (L_acc, 6); + temp = extract_l (L_acc); /* SubFrLen x curGain : avoids overflows */ + L_acc = L_mult (temp, curGain); + temp = shl (sh1, 1); + temp = add (temp, 4); + L_acc = L_shr (L_acc, temp); /* SubFrLenD x curGain**2 x 2**(-2sh1+1) */ + + /* c = (ener_ltp - SubFrLenD x curGain**2)/nb_pulses_blk */ + /* compute L_c = c >> 2sh1-1 */ + L_acc = L_sub (L_temp, L_acc); + /* x 1/nb_pulses_blk */ + L_c = L_mls (L_acc, InvNbPulsBlk); + +/* + * Solve EQ(X) = X**2 + 2 b0 X + c + */ + /* delta = b0 x b0 - c */ + b0 = mult_r (inter_exc, InvNbPulsBlk); /* b0 >> sh1 */ + L_acc = L_msu (L_c, b0, b0); /* (c - b0**2) >> 2sh1-1 */ + L_acc = L_negate (L_acc); /* delta x 2**(-2sh1+1) */ + + /* Case delta <= 0 */ + if (L_acc <= 0) { /* delta <= 0 */ + x1 = negate (b0); /* sh1 */ + } + + /* Case delta > 0 */ + else { + delta = Sqrt_lbc (L_acc); /* >> sh1 */ + x1 = sub (delta, b0); /* x1 >> sh1 */ + x2 = add (b0, delta); /* (-x2) >> sh1 */ + if (abs_s (x2) < abs_s (x1)) { + x1 = negate (x2); + } + } + + /* Update DataExc */ + sh1 = add (sh1, 1); + temp = shl (x1, sh1); + if (temp > (2 * Gexc_Max)) + temp = (2 * Gexc_Max); + if (temp < -(2 * Gexc_Max)) + temp = -(2 * Gexc_Max); + for (i = 0; i < NbPulsBlk; i++) { + j = *ptr_TabPos++; + curExc[(int) j] = add (curExc[(int) j], mult (temp, (*ptr_TabSign++))); + } + + /* update PrevExc */ + ptr1 = PrevExc; + for (i = SubFrLenD; i < PitchMax; i++) + *ptr1++ = PrevExc[i]; + for (i = 0; i < SubFrLenD; i++) + *ptr1++ = curExc[i]; + + curExc += SubFrLenD; + i_subfr += 2; + + } /* end of loop on LTP blocks */ + + return; +} + +/* +** +** Function: random_number() +** +** Description: returns a number randomly taken in [0, n] +** with np1 = n+1 at input +** +** Links to text: +** +** Arguments: +** +** Word16 np1 +** Word16 *nRandom random generator status (input/output) +** +** Outputs: +** +** Word16 *nRandom +** +** Return value: random number in [0, (np1-1)] +** +*/ +Word16 +random_number (Word16 np1, Word16 * nRandom) +{ + Word16 temp; + + temp = Rand_lbc (nRandom) & (Word16) 0x7FFF; + temp = mult (temp, np1); + return (temp); +} + +/* +** +** Function: Qua_SidGain() +** +** Description: Quantization of Sid gain +** Pseudo-log quantizer in 3 segments +** 1st segment : length = 16, resolution = 2 +** 2nd segment : length = 16, resolution = 4 +** 3rd segment : length = 32, resolution = 8 +** quantizes a sum of energies +** +** Links to text: +** +** Arguments: +** +** Word16 *Ener table of the energies +** Word16 *shEner corresponding scaling factors +** Word16 nq if nq >= 1 : quantization of nq energies +** for SID gain calculation in function Cod_Cng() +** if nq = 0 : in function Comp_Info(), +** quantization of saved estimated excitation energy +** +** Outputs: None +** +** +** Return value: index of quantized energy +** +*/ +Word16 +Qua_SidGain (Word16 * Ener, Word16 * shEner, Word16 nq) +{ + Word16 temp, iseg, iseg_p1; + Word16 j, j2, k, exp; + Word32 L_x, L_y; + Word16 sh1; + Word32 L_acc; + int i; + + if (nq == 0) { + /* Quantize energy saved for frame erasure case */ + /* L_x = 2 x average_ener */ + temp = shl (*shEner, 1); + temp = sub (16, temp); + L_acc = L_deposit_l (*Ener); + L_acc = L_shl (L_acc, temp); /* may overflow, and >> if temp < 0 */ + L_x = L_mls (L_acc, fact[0]); + } + + else { + + /* + * Compute weighted average of energies + * Ener[i] = enerR[i] x 2**(shEner[i]-14) + * L_x = k[nq] x SUM(i=0->nq-1) enerR[i] + * with k[nq] = 2 x fact_mul x fact_mul / nq x Frame + */ + sh1 = shEner[0]; + for (i = 1; i < nq; i++) { + if (shEner[i] < sh1) + sh1 = shEner[i]; + } + for (i = 0, L_x = 0L; i < nq; i++) { + temp = sub (shEner[i], sh1); + temp = shr (Ener[i], temp); + temp = mult_r (fact[nq], temp); + L_x = L_add (L_x, L_deposit_l (temp)); + } + temp = sub (15, sh1); + L_x = L_shl (L_x, temp); + } + + /* Quantize L_x */ + if (L_x >= L_bseg[2]) + return (63); + + /* Compute segment number iseg */ + if (L_x >= L_bseg[1]) { + iseg = 2; + exp = 4; + } + else { + exp = 3; + if (L_x >= L_bseg[0]) + iseg = 1; + else + iseg = 0; + } + + iseg_p1 = add (iseg, 1); + j = shl (1, exp); + k = shr (j, 1); + + /* Binary search in segment iseg */ + for (i = 0; i < exp; i++) { + temp = add (base[iseg], shl (j, iseg_p1)); + L_y = L_mult (temp, temp); + if (L_x >= L_y) + j = add (j, k); + else + j = sub (j, k); + k = shr (k, 1); + } + + temp = add (base[iseg], shl (j, iseg_p1)); + L_y = L_mult (temp, temp); + L_y = L_sub (L_y, L_x); + if (L_y <= 0L) { + j2 = add (j, 1); + temp = add (base[iseg], shl (j2, iseg_p1)); + L_acc = L_mult (temp, temp); + L_acc = L_sub (L_x, L_acc); + if (L_y > L_acc) + temp = add (shl (iseg, 4), j); + else + temp = add (shl (iseg, 4), j2); + } + else { + j2 = sub (j, 1); + temp = add (base[iseg], shl (j2, iseg_p1)); + L_acc = L_mult (temp, temp); + L_acc = L_sub (L_x, L_acc); + if (L_y < L_acc) + temp = add (shl (iseg, 4), j); + else + temp = add (shl (iseg, 4), j2); + } + return (temp); +} + +/* +** +** Function: Dec_SidGain() +** +** Description: Decoding of quantized Sid gain +** (corresponding to sqrt of average energy) +** +** Links to text: +** +** Arguments: +** +** Word16 iGain index of quantized Sid Gain +** +** Outputs: None +** +** Return value: decoded gain value << 5 +** +*/ +Word16 +Dec_SidGain (Word16 iGain) +{ + Word16 i, iseg; + Word16 temp; + + iseg = shr (iGain, 4); + if (iseg == 3) + iseg = 2; + i = sub (iGain, shl (iseg, 4)); + temp = add (iseg, 1); + temp = shl (i, temp); + temp = add (temp, base[iseg]); /* SidGain */ + temp = shl (temp, 5); /* << 5 */ + return (temp); +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/util_cng.h asterisk-1.2.1/codecs/g723_1/util_cng.h --- asterisk-1.2.1.ori/codecs/g723_1/util_cng.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/util_cng.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,17 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +*/ +/* +** +** File: "util_cng.h" +** +** Description: Function prototypes for "util_cng.c" +** +*/ + +void Calc_Exc_Rand (enum Crate WrkRate, Word16 cur_gain, Word16 * PrevExc, + Word16 * DataExc, Word16 * nRandom, LINEDEF * Line); +Word16 Qua_SidGain (Word16 * Ener, Word16 * shEner, Word16 nq); +Word16 Dec_SidGain (Word16 i_gain); diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/util_lbc.c asterisk-1.2.1/codecs/g723_1/util_lbc.c --- asterisk-1.2.1.ori/codecs/g723_1/util_lbc.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/util_lbc.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,935 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: util_lbc.c +** +** Description: utility functions for the lbc codec +** +** Functions: +** +** I/O functions: +** +** Read_lbc() +** Write_lbc() +** +** High-pass filtering: +** +** Rem_Dc() +** +** Miscellaneous signal processing functions: +** +** Vec_Norm() +** Mem_Shift() +** Comp_En() +** Scale() +** +** Bit stream packing/unpacking: +** +** Line_Pack() +** Line_Unpk() +** +** Mathematical functions: +** +** Sqrt_lbc() +** Rand_lbc() +*/ + +#include +#include + +#include "typedef.h" +#include "basop.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "coder.h" +#include "decod.h" +#include "util_lbc.h" + +/* +** +** Function: Read_lbc() +** +** Description: Read in a file +** +** Links to text: Sections 2.2 & 4 +** +** Arguments: +** +** Word16 *Dpnt +** int Len +** FILE *Fp +** +** Outputs: +** +** Word16 *Dpnt +** +** Return value: None +** +*/ +void +Read_lbc (Word16 * Dpnt, int Len, FILE * Fp) +{ + int i; + + for (i = 0; i < Len; i++) + Dpnt[i] = (Word16) 0; + + fread ((char *) Dpnt, sizeof (Word16), Len, Fp); + + return; +} + +/* +** +** Function: Write_lbc() +** +** Description: Write a file +** +** Links to text: Section +** +** Arguments: +** +** Word16 *Dpnt +** int Len +** FILE *Fp +** +** Outputs: None +** +** Return value: None +** +*/ +void +Write_lbc (Word16 * Dpnt, int Len, FILE * Fp) +{ + fwrite ((char *) Dpnt, sizeof (Word16), Len, Fp); +} + +void +Line_Wr (char *Line, FILE * Fp) +{ + Word16 Info; + int Size; + + Info = Line[0] & (Word16) 0x0003; + + /* Check frame type and rate informations */ + switch (Info) { + + case 0x0002:{ /* SID frame */ + Size = 4; + break; + } + + case 0x0003:{ /* untransmitted silence frame */ + Size = 1; + break; + } + + case 0x0001:{ /* active frame, low rate */ + Size = 20; + break; + } + + default:{ /* active frame, high rate */ + Size = 24; + } + } + fwrite (Line, Size, 1, Fp); +} + +int +Line_Rd (char *Line, FILE * Fp) +{ + Word16 Info; + int Size; + + if (fread (Line, 1, 1, Fp) != 1) + return (-1); + + Info = Line[0] & (Word16) 0x0003; + + /* Check frame type and rate informations */ + switch (Info) { + + /* Active frame, high rate */ + case 0:{ + Size = 23; + break; + } + + /* Active frame, low rate */ + case 1:{ + Size = 19; + break; + } + + /* Sid Frame */ + case 2:{ + Size = 3; + break; + } + + /* untransmitted */ + default:{ + return (0); + } + } + fread (&Line[1], Size, 1, Fp); + return (0); +} + +/* +** +** Function: Rem_Dc() +** +** Description: High-pass filtering +** +** Links to text: Section 2.3 +** +** Arguments: +** +** Word16 *Dpnt +** +** Inputs: +** +** CodStat->HpfZdl FIR filter memory from previous frame (1 word) +** CodStat->HpfPdl IIR filter memory from previous frame (1 word) +** +** Outputs: +** +** Word16 *Dpnt +** +** Return value: None +** +*/ +void +Rem_Dc (CODSTATDEF * CodStat, Word16 * Dpnt) +{ + int i; + + + Word32 Acc0, Acc1; + + if (CodStat->UseHp) { + for (i = 0; i < Frame; i++) { + + /* Do the Fir and scale by 2 */ + Acc0 = L_mult (Dpnt[i], (Word16) 0x4000); + Acc0 = L_mac (Acc0, CodStat->HpfZdl, (Word16) 0xc000); + CodStat->HpfZdl = Dpnt[i]; + + /* Do the Iir part */ + Acc1 = L_mls (CodStat->HpfPdl, (Word16) 0x7f00); + Acc0 = L_add (Acc0, Acc1); + CodStat->HpfPdl = Acc0; + Dpnt[i] = L_round (Acc0); + } + } + else { + for (i = 0; i < Frame; i++) + Dpnt[i] = shr (Dpnt[i], (Word16) 1); + } + + return; +} + +/* +** +** Function: Vec_Norm() +** +** Description: Vector normalization +** +** Links to text: +** +** Arguments: +** +** Word16 *Vect +** Word16 Len +** +** Outputs: +** +** Word16 *Vect +** +** Return value: The power of 2 by which the data vector multiplyed. +** +*/ +Word16 +Vec_Norm (Word16 * Vect, Word16 Len) +{ + int i; + + Word16 Acc0, Acc1; + Word16 Exp; + Word16 Rez; + Word32 Temp; + + static short ShiftTable[16] = { + 0x0001, + 0x0002, + 0x0004, + 0x0008, + 0x0010, + 0x0020, + 0x0040, + 0x0080, + 0x0100, + 0x0200, + 0x0400, + 0x0800, + 0x1000, + 0x2000, + 0x4000, + 0x7fff + }; + + /* Find absolute maximum */ + Acc1 = (Word16) 0; + for (i = 0; i < Len; i++) { + Acc0 = abs_s (Vect[i]); + if (Acc0 > Acc1) + Acc1 = Acc0; + } + + /* Get the shift count */ + Rez = norm_s (Acc1); + Exp = ShiftTable[Rez]; + + /* Normalize all the vector */ + for (i = 0; i < Len; i++) { + Temp = L_mult (Exp, Vect[i]); + Temp = L_shr (Temp, 4); + Vect[i] = extract_l (Temp); + } + + Rez = sub (Rez, (Word16) 3); + return Rez; +} + +/* +** +** Function: Mem_Shift() +** +** Description: Memory shift, update of the high-passed input speech signal +** +** Links to text: +** +** Arguments: +** +** Word16 *PrevDat +** Word16 *DataBuff +** +** Outputs: +** +** Word16 *PrevDat +** Word16 *DataBuff +** +** Return value: None +** +*/ +void +Mem_Shift (Word16 * PrevDat, Word16 * DataBuff) +{ + int i; + + Word16 Dpnt[Frame + LpcFrame - SubFrLen]; + + /* Form Buffer */ + for (i = 0; i < LpcFrame - SubFrLen; i++) + Dpnt[i] = PrevDat[i]; + for (i = 0; i < Frame; i++) + Dpnt[i + LpcFrame - SubFrLen] = DataBuff[i]; + + /* Update PrevDat */ + for (i = 0; i < LpcFrame - SubFrLen; i++) + PrevDat[i] = Dpnt[Frame + i]; + + /* Update DataBuff */ + for (i = 0; i < Frame; i++) + DataBuff[i] = Dpnt[(LpcFrame - SubFrLen) / 2 + i]; + + return; +} + +/* +** +** Function: Line_Pack() +** +** Description: Packing coded parameters in bitstream of 16-bit words +** +** Links to text: Section 4 +** +** Arguments: +** +** LINEDEF *Line Coded parameters for a frame +** char *Vout bitstream chars +** Word16 VadBit Voice Activity Indicator +** +** Outputs: +** +** Word16 *Vout +** +** Return value: None +** +*/ +void +Line_Pack (enum Crate WrkRate, LINEDEF * Line, char *Vout, Word16 Ftyp) +{ + int i; + int BitCount; + + Word16 BitStream[192]; + Word16 *Bsp = BitStream; + Word32 Temp; + + /* Clear the output vector */ + for (i = 0; i < 24; i++) + Vout[i] = 0; + + /* + * Add the coder rate info and frame type info to the 2 msb + * of the first word of the frame. + * The signaling is as follows: + * Ftyp WrkRate => X1X0 + * 1 Rate63 00 : High Rate + * 1 Rate53 01 : Low Rate + * 2 x 10 : Silence Insertion Descriptor frame + * 0 x 11 : Used only for simulation of + * untransmitted silence frames + */ + switch (Ftyp) { + + case 0:{ + Temp = 0x00000003L; + break; + } + + case 2:{ + Temp = 0x00000002L; + break; + } + + default:{ + if (WrkRate == Rate63) + Temp = 0x00000000L; + else + Temp = 0x00000001L; + break; + } + } + + /* Serialize Control info */ + Bsp = Par2Ser (Temp, Bsp, 2); + + + /* Check for Speech/NonSpeech case */ + if (Ftyp == 1) { + + /* 24 bit LspId */ + Temp = (*Line).LspId; + Bsp = Par2Ser (Temp, Bsp, 24); + + /* + * Do the part common to both rates + */ + + /* Adaptive code book lags */ + Temp = (Word32) (*Line).Olp[0] - (Word32) PitchMin; + Bsp = Par2Ser (Temp, Bsp, 7); + + Temp = (Word32) (*Line).Sfs[1].AcLg; + Bsp = Par2Ser (Temp, Bsp, 2); + + Temp = (Word32) (*Line).Olp[1] - (Word32) PitchMin; + Bsp = Par2Ser (Temp, Bsp, 7); + + Temp = (Word32) (*Line).Sfs[3].AcLg; + Bsp = Par2Ser (Temp, Bsp, 2); + + /* Write combined 12 bit index of all the gains */ + for (i = 0; i < SubFrames; i++) { + Temp = (*Line).Sfs[i].AcGn * NumOfGainLev + (*Line).Sfs[i].Mamp; + if (WrkRate == Rate63) + Temp += (Word32) (*Line).Sfs[i].Tran << 11; + Bsp = Par2Ser (Temp, Bsp, 12); + } + + /* Write all the Grid indices */ + for (i = 0; i < SubFrames; i++) + *Bsp++ = (*Line).Sfs[i].Grid; + + /* High rate only part */ + if (WrkRate == Rate63) { + + /* Write the reserved bit as 0 */ + *Bsp++ = (Word16) 0; + + /* Write 13 bit combined position index */ + Temp = (*Line).Sfs[0].Ppos >> 16; + Temp = Temp * 9 + ((*Line).Sfs[1].Ppos >> 14); + Temp *= 90; + Temp += ((*Line).Sfs[2].Ppos >> 16) * 9 + ((*Line).Sfs[3].Ppos >> 14); + Bsp = Par2Ser (Temp, Bsp, 13); + + /* Write all the pulse positions */ + Temp = (*Line).Sfs[0].Ppos & 0x0000ffffL; + Bsp = Par2Ser (Temp, Bsp, 16); + + Temp = (*Line).Sfs[1].Ppos & 0x00003fffL; + Bsp = Par2Ser (Temp, Bsp, 14); + + Temp = (*Line).Sfs[2].Ppos & 0x0000ffffL; + Bsp = Par2Ser (Temp, Bsp, 16); + + Temp = (*Line).Sfs[3].Ppos & 0x00003fffL; + Bsp = Par2Ser (Temp, Bsp, 14); + + /* Write pulse amplitudes */ + Temp = (Word32) (*Line).Sfs[0].Pamp; + Bsp = Par2Ser (Temp, Bsp, 6); + + Temp = (Word32) (*Line).Sfs[1].Pamp; + Bsp = Par2Ser (Temp, Bsp, 5); + + Temp = (Word32) (*Line).Sfs[2].Pamp; + Bsp = Par2Ser (Temp, Bsp, 6); + + Temp = (Word32) (*Line).Sfs[3].Pamp; + Bsp = Par2Ser (Temp, Bsp, 5); + } + + /* Low rate only part */ + else { + + /* Write 12 bits of positions */ + for (i = 0; i < SubFrames; i++) { + Temp = (*Line).Sfs[i].Ppos; + Bsp = Par2Ser (Temp, Bsp, 12); + } + + /* Write 4 bit Pamps */ + for (i = 0; i < SubFrames; i++) { + Temp = (*Line).Sfs[i].Pamp; + Bsp = Par2Ser (Temp, Bsp, 4); + } + } + + } + + else if (Ftyp == 2) { /* SID frame */ + + /* 24 bit LspId */ + Temp = (*Line).LspId; + Bsp = Par2Ser (Temp, Bsp, 24); + + /* Do Sid frame gain */ + Temp = (Word32) (*Line).Sfs[0].Mamp; + Bsp = Par2Ser (Temp, Bsp, 6); + } + + /* Write out active frames */ + if (Ftyp == 1) { + if (WrkRate == Rate63) + BitCount = 192; + else + BitCount = 160; + } + /* Non active frames */ + else if (Ftyp == 2) + BitCount = 32; + else + BitCount = 2; + + for (i = 0; i < BitCount; i++) + Vout[i >> 3] ^= BitStream[i] << (i & 0x0007); + + return; +} + +Word16 * +Par2Ser (Word32 Inp, Word16 * Pnt, int BitNum) +{ + int i; + Word16 Temp; + + for (i = 0; i < BitNum; i++) { + Temp = (Word16) Inp & (Word16) 0x0001; + Inp >>= 1; + *Pnt++ = Temp; + } + + return Pnt; +} + +/* +** +** Function: Line_Unpk() +** +** Description: unpacking of bitstream, gets coding parameters for a frame +** +** Links to text: Section 4 +** +** Arguments: +** +** char *Vinp bitstream chars +** Word16 *VadType +** +** Outputs: +** +** Word16 *VadType +** +** Return value: +** +** LINEDEF coded parameters +** Word16 Crc +** Word32 LspId +** Word16 Olp[SubFrames/2] +** SFSDEF Sfs[SubFrames] +** +*/ +LINEDEF +Line_Unpk (enum Crate * WrkRate, char *Vinp, Word16 * Ftyp, Word16 Crc) +{ + int i; + Word16 BitStream[192]; + Word16 *Bsp = BitStream; + LINEDEF Line; + Word32 Temp; + Word16 Info; + Word16 Bound_AcGn; + + Line.Crc = Crc; + if (Crc != 0) + return Line; + + /* Unpack the byte info to BitStream vector */ + for (i = 0; i < 192; i++) + BitStream[i] = (Vinp[i >> 3] >> (i & (Word16) 0x0007)) & (Word16) 1; + + /* Decode the frame type and rate info */ + Info = (Word16) Ser2Par (&Bsp, 2); + + if (Info == 3) { + *Ftyp = 0; + Line.LspId = 0L; /* Dummy : to avoid Borland C3.1 warning */ + return Line; + } + + /* Decode the LspId */ + Line.LspId = Ser2Par (&Bsp, 24); + + if (Info == 2) { + /* Decode the Noise Gain */ + Line.Sfs[0].Mamp = (Word16) Ser2Par (&Bsp, 6); + *Ftyp = 2; + return Line; + } + + /* + * Decode the common information to both rates + */ + *Ftyp = 1; + + /* Decode the bit-rate */ + *WrkRate = (Info == 0) ? Rate63 : Rate53; + + /* Decode the adaptive codebook lags */ + Temp = Ser2Par (&Bsp, 7); + /* Test if forbidden code */ + if (Temp <= 123) { + Line.Olp[0] = (Word16) Temp + (Word16) PitchMin; + } + else { + /* transmission error */ + Line.Crc = 1; + return Line; + } + + Line.Sfs[1].AcLg = (Word16) Ser2Par (&Bsp, 2); + + Temp = Ser2Par (&Bsp, 7); + /* Test if forbidden code */ + if (Temp <= 123) { + Line.Olp[1] = (Word16) Temp + (Word16) PitchMin; + } + else { + /* transmission error */ + Line.Crc = 1; + return Line; + } + + Line.Sfs[3].AcLg = (Word16) Ser2Par (&Bsp, 2); + + Line.Sfs[0].AcLg = 1; + Line.Sfs[2].AcLg = 1; + + /* Decode the combined gains accordingly to the rate */ + for (i = 0; i < SubFrames; i++) { + + Temp = Ser2Par (&Bsp, 12); + + Line.Sfs[i].Tran = 0; + Bound_AcGn = NbFilt170; + if ((*WrkRate == Rate63) && (Line.Olp[i >> 1] < (SubFrLen - 2))) { + Line.Sfs[i].Tran = (Word16) (Temp >> 11); + Temp &= 0x000007ffL; + Bound_AcGn = NbFilt085; + } + Line.Sfs[i].AcGn = (Word16) (Temp / (Word16) NumOfGainLev); + if (Line.Sfs[i].AcGn < Bound_AcGn) { + Line.Sfs[i].Mamp = (Word16) (Temp % (Word16) NumOfGainLev); + } + else { + /* error detected */ + Line.Crc = 1; + return Line; + } + } + + /* Decode the grids */ + for (i = 0; i < SubFrames; i++) + Line.Sfs[i].Grid = *Bsp++; + + if (Info == 0) { + + /* Skip the reserved bit */ + Bsp++; + + /* Decode 13 bit combined position index */ + Temp = Ser2Par (&Bsp, 13); + Line.Sfs[0].Ppos = (Temp / 90) / 9; + Line.Sfs[1].Ppos = (Temp / 90) % 9; + Line.Sfs[2].Ppos = (Temp % 90) / 9; + Line.Sfs[3].Ppos = (Temp % 90) % 9; + + /* Decode all the pulse positions */ + Line.Sfs[0].Ppos = (Line.Sfs[0].Ppos << 16) + Ser2Par (&Bsp, 16); + Line.Sfs[1].Ppos = (Line.Sfs[1].Ppos << 14) + Ser2Par (&Bsp, 14); + Line.Sfs[2].Ppos = (Line.Sfs[2].Ppos << 16) + Ser2Par (&Bsp, 16); + Line.Sfs[3].Ppos = (Line.Sfs[3].Ppos << 14) + Ser2Par (&Bsp, 14); + + /* Decode pulse amplitudes */ + Line.Sfs[0].Pamp = (Word16) Ser2Par (&Bsp, 6); + Line.Sfs[1].Pamp = (Word16) Ser2Par (&Bsp, 5); + Line.Sfs[2].Pamp = (Word16) Ser2Par (&Bsp, 6); + Line.Sfs[3].Pamp = (Word16) Ser2Par (&Bsp, 5); + } + + else { + + /* Decode the positions */ + for (i = 0; i < SubFrames; i++) + Line.Sfs[i].Ppos = Ser2Par (&Bsp, 12); + + /* Decode the amplitudes */ + for (i = 0; i < SubFrames; i++) + Line.Sfs[i].Pamp = (Word16) Ser2Par (&Bsp, 4); + } + return Line; +} + +Word32 +Ser2Par (Word16 ** Pnt, int Count) +{ + int i; + Word32 Rez = 0L; + + for (i = 0; i < Count; i++) { + Rez += (Word32) ** Pnt << i; + (*Pnt)++; + } + return Rez; +} + +/* +** +** Function: Comp_En() +** +** Description: Compute energy of a subframe vector +** +** Links to text: +** +** Arguments: +** +** Word16 *Dpnt +** +** Outputs: None +** +** Return value: +** +** Word32 energy +** +*/ +Word32 +Comp_En (Word16 * Dpnt) +{ + int i; + Word32 Rez; + Word16 Temp[SubFrLen]; + + for (i = 0; i < SubFrLen; i++) + Temp[i] = shr (Dpnt[i], (Word16) 2); + + Rez = (Word32) 0; + for (i = 0; i < SubFrLen; i++) + Rez = L_mac (Rez, Temp[i], Temp[i]); + + return Rez; +} + +/* +** +** Function: Sqrt_lbc() +** +** Description: Square root computation +** +** Links to text: +** +** Arguments: +** +** Word32 Num +** +** Outputs: None +** +** Return value: +** +** Word16 square root of num +** +*/ +Word16 +Sqrt_lbc (Word32 Num) +{ + int i; + + Word16 Rez = (Word16) 0; + Word16 Exp = (Word16) 0x4000; + + Word32 Acc; + + for (i = 0; i < 14; i++) { + + Acc = L_mult (add (Rez, Exp), add (Rez, Exp)); + if (Num >= Acc) + Rez = add (Rez, Exp); + + Exp = shr (Exp, (Word16) 1); + } + return Rez; +} + +/* +** +** Function: Rand_lbc() +** +** Description: Generator of random numbers +** +** Links to text: Section 3.10.2 +** +** Arguments: +** +** Word16 *p +** +** Outputs: +** +** Word16 *p +** +** Return value: +** +** Word16 random number +** +*/ +Word16 +Rand_lbc (Word16 * p) +{ + Word32 Temp; + + Temp = L_deposit_l (*p); + Temp &= (Word32) 0x0000ffff; + Temp = Temp * (Word32) 521 + (Word32) 259; + *p = extract_l (Temp); + return extract_l (Temp); +} + +/* +** +** Function: Scale() +** +** Description: Postfilter gain scaling +** +** Links to text: Section 3.9 +** +** Arguments: +** +** Word16 *Tv +** Word32 Sen +** +** Inputs: +** +** Word16 DecStat->Gain +** +** Outputs: +** +** Word16 *Tv +** +** Return value: new gain +** +*/ +Word16 +Scale (Word16 Gain, Word16 * Tv, Word32 Sen) +{ + int i; + + Word32 Acc0, Acc1; + Word16 Exp, SfGain; + + + Acc0 = Sen; + Acc1 = Comp_En (Tv); + + /* Normalize both */ + if ((Acc1 != (Word32) 0) && (Acc0 != (Word32) 0)) { + + Exp = norm_l (Acc1); + Acc1 = L_shl (Acc1, Exp); + + SfGain = norm_l (Acc0); + Acc0 = L_shl (Acc0, SfGain); + Acc0 = L_shr (Acc0, (Word16) 1); + Exp = sub (Exp, SfGain); + Exp = add (Exp, (Word16) 1); + Exp = sub ((Word16) 6, Exp); + if (Exp < (Word16) 0) + Exp = (Word16) 0; + + SfGain = extract_h (Acc1); + + SfGain = div_l (Acc0, SfGain); + + Acc0 = L_deposit_h (SfGain); + + Acc0 = L_shr (Acc0, Exp); + + SfGain = Sqrt_lbc (Acc0); + } + else + SfGain = 0x1000; + + /* Filter the data */ + for (i = 0; i < SubFrLen; i++) { + + /* Update gain */ + Acc0 = L_deposit_h (Gain); + Acc0 = L_msu (Acc0, Gain, (Word16) 0x0800); + Acc0 = L_mac (Acc0, SfGain, (Word16) 0x0800); + Gain = L_round (Acc0); + + Exp = add (Gain, shr (Gain, (Word16) 4)); + + Acc0 = L_mult (Tv[i], Exp); + Acc0 = L_shl (Acc0, (Word16) 4); + Tv[i] = L_round (Acc0); + } + + return Gain; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/util_lbc.h asterisk-1.2.1/codecs/g723_1/util_lbc.h --- asterisk-1.2.1.ori/codecs/g723_1/util_lbc.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/util_lbc.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,33 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "util_lbc.h" +** +** Description: Function prototypes for "util_lbc.c" +** +*/ + +#include "coder.h" + + +void Read_lbc (Word16 * Dpnt, int Len, FILE * Fp); +void Write_lbc (Word16 * Dpnt, int Len, FILE * Fp); +void Rem_Dc (CODSTATDEF * CodStat, Word16 * Dpnt); +Word16 Vec_Norm (Word16 * Vect, Word16 Len); +void Mem_Shift (Word16 * PrevDat, Word16 * DataBuff); +Word16 *Par2Ser (Word32 Inp, Word16 * Pnt, int BitNum); + +void Line_Pack (enum Crate WrkRate, LINEDEF * Line, char *Vout, Word16 Ftyp); +LINEDEF Line_Unpk (enum Crate *WrkRate, char *Vinp, Word16 * Ftyp, + Word16 Crc); + +Word32 Ser2Par (Word16 ** Pnt, int Count); +Word32 Comp_En (Word16 * Dpnt); +Word16 Sqrt_lbc (Word32 Num); +Word16 Rand_lbc (Word16 * p); +Word16 Scale (Word16 Gain, Word16 * Tv, Word32 Sen); + +void Line_Wr (char *, FILE *); +int Line_Rd (char *, FILE *); diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/vad.c asterisk-1.2.1/codecs/g723_1/vad.c --- asterisk-1.2.1.ori/codecs/g723_1/vad.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/vad.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,193 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "vad.c" +** +** Description: Voice Activity Detection +** +** Functions: Init_Vad() +** Vad() +** +** +*/ + +#include + +#include "typedef.h" +#include "basop.h" +#include "cst_lbc.h" +#include "tab_lbc.h" +#include "lsp.h" +#include "vad.h" +#include "coder.h" + +void +Init_Vad (CODSTATDEF * CodStat) +{ + int i; + CodStat->Hcnt = 3; + CodStat->Vcnt = 0; + CodStat->Penr = 0x00000400L; + CodStat->Nlev = 0x00000400L; + + CodStat->Aen = 0; + + CodStat->Polp[0] = 1; + CodStat->Polp[1] = 1; + CodStat->Polp[2] = SubFrLen; + CodStat->Polp[3] = SubFrLen; + + for (i = 0; i < LpcOrder; i++) + CodStat->NLpc[i] = 0; + +} + +Flag +Comp_Vad (CODSTATDEF * CodStat, Word16 * Dpnt) +{ + int i, j; + + Word32 Acc0, Acc1; + Word16 Tm0, Tm1, Tm2; + Word16 Minp; + + Flag VadState = 1; + + static Word16 ScfTab[11] = { + 9170, + 9170, + 9170, + 9170, + 10289, + 11544, + 12953, + 14533, + 16306, + 18296, + 20529, + }; + + if (!CodStat->UseVx) + return VadState; + + /* Find Minimum pitch period */ + Minp = PitchMax; + for (i = 0; i < 4; i++) { + if (Minp > CodStat->Polp[i]) + Minp = CodStat->Polp[i]; + } + + /* Check that all are multiplies of the minimum */ + Tm2 = 0; + for (i = 0; i < 4; i++) { + Tm1 = Minp; + for (j = 0; j < 8; j++) { + Tm0 = sub (Tm1, CodStat->Polp[i]); + Tm0 = abs_s (Tm0); + if (Tm0 <= 3) + Tm2++; + Tm1 = add (Tm1, Minp); + } + } + + /* Update adaptation enable counter if not periodic and not sine */ + if ((Tm2 == 4) || (CodStat->SinDet < 0)) + CodStat->Aen += 2; + else + CodStat->Aen--; + + /* Clip it */ + if (CodStat->Aen > 6) + CodStat->Aen = 6; + if (CodStat->Aen < 0) + CodStat->Aen = 0; + + /* Inverse filter the data */ + Acc1 = 0L; + for (i = SubFrLen; i < Frame; i++) { + + Acc0 = L_mult (Dpnt[i], 0x2000); + for (j = 0; j < LpcOrder; j++) + Acc0 = L_msu (Acc0, Dpnt[i - j - 1], CodStat->NLpc[j]); + Tm0 = L_round (Acc0); + Acc1 = L_mac (Acc1, Tm0, Tm0); + } + + /* Scale the rezidual energy */ + Acc1 = L_mls (Acc1, (Word16) 2913); + + /* Clip noise level in any case */ + if (CodStat->Nlev > CodStat->Penr) { + Acc0 = L_sub (CodStat->Penr, L_shr (CodStat->Penr, 2)); + CodStat->Nlev = L_add (Acc0, L_shr (CodStat->Nlev, 2)); + } + + + /* Update the noise level, if adaptation is enabled */ + if (!CodStat->Aen) { + CodStat->Nlev = L_add (CodStat->Nlev, L_shr (CodStat->Nlev, 5)); + } + /* Decay Nlev by small amount */ + else { + CodStat->Nlev = L_sub (CodStat->Nlev, L_shr (CodStat->Nlev, 11)); + } + + /* Update previous energy */ + CodStat->Penr = Acc1; + + /* CLip Noise Level */ + if (CodStat->Nlev < 0x00000080L) + CodStat->Nlev = 0x00000080L; + if (CodStat->Nlev > 0x0001ffffL) + CodStat->Nlev = 0x0001ffffL; + + /* Compute the treshold */ + Acc0 = L_shl (CodStat->Nlev, 13); + Tm0 = norm_l (Acc0); + Acc0 = L_shl (Acc0, Tm0); + Acc0 &= 0x3f000000L; + Acc0 <<= 1; + Tm1 = extract_h (Acc0); + Acc0 = L_deposit_h (ScfTab[Tm0]); + Acc0 = L_mac (Acc0, Tm1, ScfTab[Tm0 - 1]); + Acc0 = L_msu (Acc0, Tm1, ScfTab[Tm0]); + Tm1 = extract_h (Acc0); + Tm0 = extract_l (L_shr (CodStat->Nlev, 2)); + Acc0 = L_mult (Tm0, Tm1); + Acc0 >>= 11; + + /* Compare with the treshold */ + if (Acc0 > Acc1) + VadState = 0; + + /* Do the various counters */ + if (VadState) { + CodStat->Vcnt++; + CodStat->Hcnt++; + } + else { + CodStat->Vcnt--; + if (CodStat->Vcnt < 0) + CodStat->Vcnt = 0; + } + + if (CodStat->Vcnt >= 2) { + CodStat->Hcnt = 6; + if (CodStat->Vcnt >= 3) + CodStat->Vcnt = 3; + } + + if (CodStat->Hcnt) { + VadState = 1; + if (CodStat->Vcnt == 0) + CodStat->Hcnt--; + } + + /* Update Periodicy detector */ + CodStat->Polp[0] = CodStat->Polp[2]; + CodStat->Polp[1] = CodStat->Polp[3]; + + return VadState; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g723_1/vad.h asterisk-1.2.1/codecs/g723_1/vad.h --- asterisk-1.2.1.ori/codecs/g723_1/vad.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g723_1/vad.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,15 @@ +/* +** ITU-T G.723 Speech Coder ANSI-C Source Code Version 5.00 +** copyright (c) 1995, AudioCodes, DSP Group, France Telecom, +** Universite de Sherbrooke. All rights reserved. +** +** File: "vad.h" +** +** Description: Function prototypes for "vad.c" +** +*/ + +#include "coder.h" + +void Init_Vad (CODSTATDEF * CodStat); +Flag Comp_Vad (CODSTATDEF * CodStat, Word16 * Dpnt); diff -u -N -r asterisk-1.2.1.ori/codecs/g729_slin_ex.h asterisk-1.2.1/codecs/g729_slin_ex.h --- asterisk-1.2.1.ori/codecs/g729_slin_ex.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729_slin_ex.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,7 @@ +/* + * One frame of raw G729 data + */ + +static unsigned char g729_slin_ex[] = { + 0xf9, 0xa3, 0xc9, 0xe0, 0x0, 0xfa, 0xdd, 0xa9, 0x97, 0x7d }; + diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/Makefile asterisk-1.2.1/codecs/g729a_v11/Makefile --- asterisk-1.2.1.ori/codecs/g729a_v11/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/Makefile 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,48 @@ +ARCH=$(PROC) +CFLAGS+=-Wall -O3 -funroll-loops +ifneq (${OSARCH},CYGWIN) +CFLAGS += -fPIC +endif +LIB=libg729.a + +OBJS=\ +acelp_ca.o \ +basic_op.o \ +cod_ld8a.o \ +cor_func.o \ +de_acelp.o \ +dec_gain.o \ +dec_lag3.o \ +dec_ld8a.o \ +dspfunc.o \ +filter.o \ +gainpred.o \ +lpc.o \ +lpcfunc.o \ +lspdec.o \ +lspgetq.o \ +oper_32b.o \ +pitch_a.o \ +postfilt.o \ +post_pro.o \ +p_parity.o \ +pred_lt3.o \ +pre_proc.o \ +qua_gain.o \ +qua_lsp.o \ +tab_ld8a.o \ +taming.o \ +util.o + +all: $(LIB) + + +$(LIB): $(OBJS) + ar cr $(LIB) $(OBJS) + ranlib $(LIB) + +clean: + rm -f $(LIB) *.o + +install: + diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/acelp_ca.c asterisk-1.2.1/codecs/g729a_v11/acelp_ca.c --- asterisk-1.2.1.ori/codecs/g729a_v11/acelp_ca.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/acelp_ca.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,990 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*---------------------------------------------------------------------------* + * Function ACELP_Code_A() * + * ~~~~~~~~~~~~~~~~~~~~~~~~ * + * Find Algebraic codebook for G.729A * + *--------------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +/* Constants defined in ld8a.h */ +/* L_SUBFR -> Lenght of subframe. */ +/* NB_POS -> Number of positions for each pulse. */ +/* STEP -> Step betweem position of the same pulse. */ +/* MSIZE -> Size of vectors for cross-correlation between two pulses. */ + + +/* local routines definition */ + +void Cor_h (Word16 * H, /* (i) Q12 :Impulse response of filters */ + Word16 * rr /* (o) :Correlations of H[] */ +); +Word16 D4i40_17_fast ( /*(o) : Index of pulses positions. */ + Word16 dn[], /* (i) : Correlations between h[] and Xn[]. */ + Word16 * rr, /* (i) : Correlations of impulse response h[]. */ + Word16 h[], /* (i) Q12: Impulse response of filters. */ + Word16 cod[], /* (o) Q13: Selected algebraic codeword. */ + Word16 y[], /* (o) Q12: Filtered algebraic codeword. */ + Word16 * sign /* (o) : Signs of 4 pulses. */ + ); + + /*-----------------------------------------------------------------* + * Main ACELP function. * + *-----------------------------------------------------------------*/ + +Word16 +ACELP_Code_A ( /* (o) :index of pulses positions */ + Word16 x[], /* (i) :Target vector */ + Word16 h[], /* (i) Q12 :Inpulse response of filters */ + Word16 T0, /* (i) :Pitch lag */ + Word16 pitch_sharp, /* (i) Q14 :Last quantized pitch gain */ + Word16 code[], /* (o) Q13 :Innovative codebook */ + Word16 y[], /* (o) Q12 :Filtered innovative codebook */ + Word16 * sign /* (o) :Signs of 4 pulses */ + ) +{ + Word16 i, index, sharp; + Word16 Dn[L_SUBFR]; + Word16 rr[DIM_RR]; + + /*-----------------------------------------------------------------* + * Include fixed-gain pitch contribution into impulse resp. h[] * + * Find correlations of h[] needed for the codebook search. * + *-----------------------------------------------------------------*/ + + sharp = shl (pitch_sharp, 1); /* From Q14 to Q15 */ + if (T0 < L_SUBFR) + for (i = T0; i < L_SUBFR; i++) /* h[i] += pitch_sharp*h[i-T0] */ + h[i] = add (h[i], mult (h[i - T0], sharp)); + + Cor_h (h, rr); + + /*-----------------------------------------------------------------* + * Compute correlation of target vector with impulse response. * + *-----------------------------------------------------------------*/ + + Cor_h_X (h, x, Dn); + + /*-----------------------------------------------------------------* + * Find innovative codebook. * + *-----------------------------------------------------------------*/ + + index = D4i40_17_fast (Dn, rr, h, code, y, sign); + + /*-----------------------------------------------------------------* + * Compute innovation vector gain. * + * Include fixed-gain pitch contribution into code[]. * + *-----------------------------------------------------------------*/ + + if (T0 < L_SUBFR) + for (i = T0; i < L_SUBFR; i++) /* code[i] += pitch_sharp*code[i-T0] */ + code[i] = add (code[i], mult (code[i - T0], sharp)); + + return index; +} + + + +/*--------------------------------------------------------------------------* + * Function Cor_h() * + * ~~~~~~~~~~~~~~~~~ * + * Compute correlations of h[] needed for the codebook search. * + *--------------------------------------------------------------------------*/ + +void +Cor_h (Word16 * H, /* (i) Q12 :Impulse response of filters */ + Word16 * rr /* (o) :Correlations of H[] */ + ) +{ + Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4; + Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4; + Word16 *rri1i2, *rri1i3, *rri1i4; + Word16 *rri2i3, *rri2i4; + + Word16 *p0, *p1, *p2, *p3, *p4; + + Word16 *ptr_hd, *ptr_hf, *ptr_h1, *ptr_h2; + Word32 cor; + Word16 i, k, ldec, l_fin_sup, l_fin_inf; + Word16 h[L_SUBFR]; + + /* Scaling h[] for maximum precision */ + + cor = 0; + for (i = 0; i < L_SUBFR; i++) + cor = L_mac (cor, H[i], H[i]); + + if (sub (extract_h (cor), 32000) > 0) { + for (i = 0; i < L_SUBFR; i++) { + h[i] = shr (H[i], 1); + } + } + else { + k = norm_l (cor); + k = shr (k, 1); + + for (i = 0; i < L_SUBFR; i++) { + h[i] = shl (H[i], k); + } + } + + + /*------------------------------------------------------------* + * Compute rri0i0[], rri1i1[], rri2i2[], rri3i3 and rri4i4[] * + *------------------------------------------------------------*/ + /* Init pointers */ + rri0i0 = rr; + rri1i1 = rri0i0 + NB_POS; + rri2i2 = rri1i1 + NB_POS; + rri3i3 = rri2i2 + NB_POS; + rri4i4 = rri3i3 + NB_POS; + rri0i1 = rri4i4 + NB_POS; + rri0i2 = rri0i1 + MSIZE; + rri0i3 = rri0i2 + MSIZE; + rri0i4 = rri0i3 + MSIZE; + rri1i2 = rri0i4 + MSIZE; + rri1i3 = rri1i2 + MSIZE; + rri1i4 = rri1i3 + MSIZE; + rri2i3 = rri1i4 + MSIZE; + rri2i4 = rri2i3 + MSIZE; + + p0 = rri0i0 + NB_POS - 1; /* Init pointers to last position of rrixix[] */ + p1 = rri1i1 + NB_POS - 1; + p2 = rri2i2 + NB_POS - 1; + p3 = rri3i3 + NB_POS - 1; + p4 = rri4i4 + NB_POS - 1; + + ptr_h1 = h; + cor = 0; + for (i = 0; i < NB_POS; i++) { + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p4-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p3-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p2-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p1-- = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h1); + ptr_h1++; + *p0-- = extract_h (cor); + } + + /*-----------------------------------------------------------------* + * Compute elements of: rri2i3[], rri1i2[], rri0i1[] and rri0i4[] * + *-----------------------------------------------------------------*/ + + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + ldec = NB_POS + 1; + + ptr_hd = h; + ptr_hf = ptr_hd + 1; + + for (k = 0; k < NB_POS; k++) { + + p3 = rri2i3 + l_fin_sup; + p2 = rri1i2 + l_fin_sup; + p1 = rri0i1 + l_fin_sup; + p0 = rri0i4 + l_fin_inf; + + cor = 0; + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /*---------------------------------------------------------------------* + * Compute elements of: rri2i4[], rri1i3[], rri0i2[], rri1i4[], rri0i3 * + *---------------------------------------------------------------------*/ + + ptr_hd = h; + ptr_hf = ptr_hd + 2; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p4 = rri2i4 + l_fin_sup; + p3 = rri1i3 + l_fin_sup; + p2 = rri0i2 + l_fin_sup; + p1 = rri1i4 + l_fin_inf; + p0 = rri0i3 + l_fin_inf; + + cor = 0; + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p4 -= ldec; + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /*----------------------------------------------------------------------* + * Compute elements of: rri1i4[], rri0i3[], rri2i4[], rri1i3[], rri0i2 * + *----------------------------------------------------------------------*/ + + ptr_hd = h; + ptr_hf = ptr_hd + 3; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p4 = rri1i4 + l_fin_sup; + p3 = rri0i3 + l_fin_sup; + p2 = rri2i4 + l_fin_inf; + p1 = rri1i3 + l_fin_inf; + p0 = rri0i2 + l_fin_inf; + + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + cor = 0; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p4 -= ldec; + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p4 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + + /*----------------------------------------------------------------------* + * Compute elements of: rri0i4[], rri2i3[], rri1i2[], rri0i1[] * + *----------------------------------------------------------------------*/ + + ptr_hd = h; + ptr_hf = ptr_hd + 4; + l_fin_sup = MSIZE - 1; + l_fin_inf = l_fin_sup - (Word16) 1; + for (k = 0; k < NB_POS; k++) { + + p3 = rri0i4 + l_fin_sup; + p2 = rri2i3 + l_fin_inf; + p1 = rri1i2 + l_fin_inf; + p0 = rri0i1 + l_fin_inf; + + ptr_h1 = ptr_hd; + ptr_h2 = ptr_hf; + cor = 0; + for (i = k + (Word16) 1; i < NB_POS; i++) { + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p2 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p1 = extract_h (cor); + + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p0 = extract_h (cor); + + p3 -= ldec; + p2 -= ldec; + p1 -= ldec; + p0 -= ldec; + } + cor = L_mac (cor, *ptr_h1, *ptr_h2); + ptr_h1++; + ptr_h2++; + *p3 = extract_h (cor); + + l_fin_sup -= NB_POS; + l_fin_inf--; + ptr_hf += STEP; + } + return; +} + + + +/*------------------------------------------------------------------------* + * Function D4i40_17_fast() * + * ~~~~~~~~~ * + * Algebraic codebook for ITU 8kb/s. * + * -> 17 bits; 4 pulses in a frame of 40 samples * + * * + *------------------------------------------------------------------------* + * The code length is 40, containing 4 nonzero pulses i0, i1, i2, i3. * + * Each pulses can have 8 possible positions (positive or negative) * + * except i3 that have 16 possible positions. * + * * + * i0 (+-1) : 0, 5, 10, 15, 20, 25, 30, 35 * + * i1 (+-1) : 1, 6, 11, 16, 21, 26, 31, 36 * + * i2 (+-1) : 2, 7, 12, 17, 22, 27, 32, 37 * + * i3 (+-1) : 3, 8, 13, 18, 23, 28, 33, 38 * + * 4, 9, 14, 19, 24, 29, 34, 39 * + *------------------------------------------------------------------------*/ + +Word16 +D4i40_17_fast ( /*(o) : Index of pulses positions. */ + Word16 dn[], /* (i) : Correlations between h[] and Xn[]. */ + Word16 rr[], /* (i) : Correlations of impulse response h[]. */ + Word16 h[], /* (i) Q12: Impulse response of filters. */ + Word16 cod[], /* (o) Q13: Selected algebraic codeword. */ + Word16 y[], /* (o) Q12: Filtered algebraic codeword. */ + Word16 * sign /* (o) : Signs of 4 pulses. */ + ) +{ + Word16 i0, i1, i2, i3, ip0, ip1, ip2, ip3; + Word16 i, j, ix, iy, track, trk, max; + Word16 prev_i0, i1_offset; + Word16 psk, ps, ps0, ps1, ps2, sq, sq2; + Word16 alpk, alp, alp_16; + Word32 s, alp0, alp1, alp2; + Word16 *p0, *p1, *p2, *p3, *p4; + Word16 sign_dn[L_SUBFR], sign_dn_inv[L_SUBFR], *psign; + Word16 tmp_vect[NB_POS]; + Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4; + Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4; + Word16 *rri1i2, *rri1i3, *rri1i4; + Word16 *rri2i3, *rri2i4; + + Word16 *ptr_rri0i3_i4; + Word16 *ptr_rri1i3_i4; + Word16 *ptr_rri2i3_i4; + Word16 *ptr_rri3i3_i4; + + /* Init pointers */ + rri0i0 = rr; + rri1i1 = rri0i0 + NB_POS; + rri2i2 = rri1i1 + NB_POS; + rri3i3 = rri2i2 + NB_POS; + rri4i4 = rri3i3 + NB_POS; + rri0i1 = rri4i4 + NB_POS; + rri0i2 = rri0i1 + MSIZE; + rri0i3 = rri0i2 + MSIZE; + rri0i4 = rri0i3 + MSIZE; + rri1i2 = rri0i4 + MSIZE; + rri1i3 = rri1i2 + MSIZE; + rri1i4 = rri1i3 + MSIZE; + rri2i3 = rri1i4 + MSIZE; + rri2i4 = rri2i3 + MSIZE; + + /*-----------------------------------------------------------------------* + * Chose the sign of the impulse. * + *-----------------------------------------------------------------------*/ + + for (i = 0; i < L_SUBFR; i++) { + if (dn[i] >= 0) { + sign_dn[i] = MAX_16; + sign_dn_inv[i] = MIN_16; + } + else { + sign_dn[i] = MIN_16; + sign_dn_inv[i] = MAX_16; + dn[i] = negate (dn[i]); + } + } + + /*-------------------------------------------------------------------* + * Modification of rrixiy[] to take signs into account. * + *-------------------------------------------------------------------*/ + + p0 = rri0i1; + p1 = rri0i2; + p2 = rri0i3; + p3 = rri0i4; + + for (i0 = 0; i0 < L_SUBFR; i0 += STEP) { + psign = sign_dn; + if (psign[i0] < 0) + psign = sign_dn_inv; + + for (i1 = 1; i1 < L_SUBFR; i1 += STEP) { + *p0 = mult (*p0, psign[i1]); p0++; + *p1 = mult (*p1, psign[i1 + 1]); p1++; + *p2 = mult (*p2, psign[i1 + 2]); p2++; + *p3 = mult (*p3, psign[i1 + 3]); p3++; + } + } + + p0 = rri1i2; + p1 = rri1i3; + p2 = rri1i4; + + for (i1 = 1; i1 < L_SUBFR; i1 += STEP) { + psign = sign_dn; + if (psign[i1] < 0) + psign = sign_dn_inv; + + for (i2 = 2; i2 < L_SUBFR; i2 += STEP) { + *p0 = mult (*p0, psign[i2]); p0++; + *p1 = mult (*p1, psign[i2 + 1]); p1++; + *p2 = mult (*p2, psign[i2 + 2]); p2++; + } + } + + p0 = rri2i3; + p1 = rri2i4; + + for (i2 = 2; i2 < L_SUBFR; i2 += STEP) { + psign = sign_dn; + if (psign[i2] < 0) + psign = sign_dn_inv; + + for (i3 = 3; i3 < L_SUBFR; i3 += STEP) { + *p0 = mult (*p0, psign[i3]); p0++; + *p1 = mult (*p1, psign[i3 + 1]); p1++; + } + } + + + /*-------------------------------------------------------------------* + * Search the optimum positions of the four pulses which maximize * + * square(correlation) / energy * + *-------------------------------------------------------------------*/ + + psk = -1; + alpk = 1; + + ptr_rri0i3_i4 = rri0i3; + ptr_rri1i3_i4 = rri1i3; + ptr_rri2i3_i4 = rri2i3; + ptr_rri3i3_i4 = rri3i3; + + /* Initializations only to remove warning from some compilers */ + + ip0 = 0; + ip1 = 1; + ip2 = 2; + ip3 = 3; + ix = 0; + iy = 0; + ps = 0; + + /* search 2 times: track 3 and 4 */ + for (track = 3, trk = 0; track < 5; track++, trk++) { + /*------------------------------------------------------------------* + * depth first search 3, phase A: track 2 and 3/4. * + *------------------------------------------------------------------*/ + + sq = -1; + alp = 1; + + /* i0 loop: 2 positions in track 2 */ + + prev_i0 = -1; + + for (i = 0; i < 2; i++) { + max = -1; + /* search "dn[]" maximum position in track 2 */ + for (j = 2; j < L_SUBFR; j += STEP) { + if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) { + max = dn[j]; + i0 = j; + } + } + prev_i0 = i0; + + j = mult (i0, 6554); /* j = i0/5 */ + p0 = rri2i2 + j; + + ps1 = dn[i0]; + alp1 = L_mult (*p0, _1_4); + + /* i1 loop: 8 positions in track 2 */ + + p0 = ptr_rri2i3_i4 + shl (j, 3); + p1 = ptr_rri3i3_i4; + + for (i1 = track; i1 < L_SUBFR; i1 += STEP) { + ps2 = add (ps1, dn[i1]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ + alp2 = L_mac (alp1, *p0++, _1_2); + alp2 = L_mac (alp2, *p1++, _1_4); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + ps = ps2; + alp = alp_16; + ix = i0; + iy = i1; + } + } + } + + i0 = ix; + i1 = iy; + i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */ + + /*------------------------------------------------------------------* + * depth first search 3, phase B: track 0 and 1. * + *------------------------------------------------------------------*/ + + ps0 = ps; + alp0 = L_mult (alp, _1_4); + + sq = -1; + alp = 1; + + /* build vector for next loop to decrease complexity */ + + p0 = rri1i2 + mult (i0, 6554); + p1 = ptr_rri1i3_i4 + mult (i1, 6554); + p2 = rri1i1; + p3 = tmp_vect; + + for (i3 = 1; i3 < L_SUBFR; i3 += STEP) { + /* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */ + s = L_mult (*p0, _1_4); + p0 += NB_POS; + s = L_mac (s, *p1, _1_4); + p1 += NB_POS; + s = L_mac (s, *p2++, _1_8); + *p3++ = wround (s); + } + + /* i2 loop: 8 positions in track 0 */ + + p0 = rri0i2 + mult (i0, 6554); + p1 = ptr_rri0i3_i4 + mult (i1, 6554); + p2 = rri0i0; + p3 = rri0i1; + + for (i2 = 0; i2 < L_SUBFR; i2 += STEP) { + ps1 = add (ps0, dn[i2]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ + alp1 = L_mac (alp0, *p0, _1_8); + p0 += NB_POS; + alp1 = L_mac (alp1, *p1, _1_8); + p1 += NB_POS; + alp1 = L_mac (alp1, *p2++, _1_16); + + /* i3 loop: 8 positions in track 1 */ + + p4 = tmp_vect; + + for (i3 = 1; i3 < L_SUBFR; i3 += STEP) { + ps2 = add (ps1, dn[i3]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */ + alp2 = L_mac (alp1, *p3++, _1_8); + alp2 = L_mac (alp2, *p4++, _1_2); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + alp = alp_16; + ix = i2; + iy = i3; + } + } + } + + /*----------------------------------------------------------------* + * depth first search 3: compare codevector with the best case. * + *----------------------------------------------------------------*/ + + s = L_msu (L_mult (alpk, sq), psk, alp); + if (s > 0) { + psk = sq; + alpk = alp; + ip2 = i0; + ip3 = i1; + ip0 = ix; + ip1 = iy; + } + + /*------------------------------------------------------------------* + * depth first search 4, phase A: track 3 and 0. * + *------------------------------------------------------------------*/ + + sq = -1; + alp = 1; + + /* i0 loop: 2 positions in track 3/4 */ + + prev_i0 = -1; + + for (i = 0; i < 2; i++) { + max = -1; + /* search "dn[]" maximum position in track 3/4 */ + for (j = track; j < L_SUBFR; j += STEP) { + if ((sub (dn[j], max) > 0) && (sub (prev_i0, j) != 0)) { + max = dn[j]; + i0 = j; + } + } + prev_i0 = i0; + + j = mult (i0, 6554); /* j = i0/5 */ + p0 = ptr_rri3i3_i4 + j; + + ps1 = dn[i0]; + alp1 = L_mult (*p0, _1_4); + + /* i1 loop: 8 positions in track 0 */ + + p0 = ptr_rri0i3_i4 + j; + p1 = rri0i0; + + for (i1 = 0; i1 < L_SUBFR; i1 += STEP) { + ps2 = add (ps1, dn[i1]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ + alp2 = L_mac (alp1, *p0, _1_2); + p0 += NB_POS; + alp2 = L_mac (alp2, *p1++, _1_4); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + ps = ps2; + alp = alp_16; + ix = i0; + iy = i1; + } + } + } + + i0 = ix; + i1 = iy; + i1_offset = shl (mult (i1, 6554), 3); /* j = 8*(i1/5) */ + + /*------------------------------------------------------------------* + * depth first search 4, phase B: track 1 and 2. * + *------------------------------------------------------------------*/ + + ps0 = ps; + alp0 = L_mult (alp, _1_4); + + sq = -1; + alp = 1; + + /* build vector for next loop to decrease complexity */ + + p0 = ptr_rri2i3_i4 + mult (i0, 6554); + p1 = rri0i2 + i1_offset; + p2 = rri2i2; + p3 = tmp_vect; + + for (i3 = 2; i3 < L_SUBFR; i3 += STEP) { + /* rrv[i3] = rr[i3][i3] + rr[i0][i3] + rr[i1][i3]; */ + s = L_mult (*p0, _1_4); + p0 += NB_POS; + s = L_mac (s, *p1++, _1_4); + s = L_mac (s, *p2++, _1_8); + *p3++ = wround (s); + } + + /* i2 loop: 8 positions in track 1 */ + + p0 = ptr_rri1i3_i4 + mult (i0, 6554); + p1 = rri0i1 + i1_offset; + p2 = rri1i1; + p3 = rri1i2; + + for (i2 = 1; i2 < L_SUBFR; i2 += STEP) { + ps1 = add (ps0, dn[i2]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ + alp1 = L_mac (alp0, *p0, _1_8); + p0 += NB_POS; + alp1 = L_mac (alp1, *p1++, _1_8); + alp1 = L_mac (alp1, *p2++, _1_16); + + /* i3 loop: 8 positions in track 2 */ + + p4 = tmp_vect; + + for (i3 = 2; i3 < L_SUBFR; i3 += STEP) { + ps2 = add (ps1, dn[i3]); /* index increment = STEP */ + + /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */ + alp2 = L_mac (alp1, *p3++, _1_8); + alp2 = L_mac (alp2, *p4++, _1_2); + + sq2 = mult (ps2, ps2); + alp_16 = wround (alp2); + + s = L_msu (L_mult (alp, sq2), sq, alp_16); + if (s > 0) { + sq = sq2; + alp = alp_16; + ix = i2; + iy = i3; + } + } + } + + /*----------------------------------------------------------------* + * depth first search 1: compare codevector with the best case. * + *----------------------------------------------------------------*/ + + s = L_msu (L_mult (alpk, sq), psk, alp); + if (s > 0) { + psk = sq; + alpk = alp; + ip3 = i0; + ip0 = i1; + ip1 = ix; + ip2 = iy; + } + + ptr_rri0i3_i4 = rri0i4; + ptr_rri1i3_i4 = rri1i4; + ptr_rri2i3_i4 = rri2i4; + ptr_rri3i3_i4 = rri4i4; + + } + + + /* Set the sign of impulses */ + + i0 = sign_dn[ip0]; + i1 = sign_dn[ip1]; + i2 = sign_dn[ip2]; + i3 = sign_dn[ip3]; + + /* Find the codeword corresponding to the selected positions */ + + + for (i = 0; i < L_SUBFR; i++) { + cod[i] = 0; + } + + cod[ip0] = shr (i0, 2); /* From Q15 to Q13 */ + cod[ip1] = shr (i1, 2); + cod[ip2] = shr (i2, 2); + cod[ip3] = shr (i3, 2); + + /* find the filtered codeword */ + + for (i = 0; i < ip0; i++) + y[i] = 0; + + if (i0 > 0) + for (i = ip0, j = 0; i < L_SUBFR; i++, j++) + y[i] = h[j]; + else + for (i = ip0, j = 0; i < L_SUBFR; i++, j++) + y[i] = negate (h[j]); + + if (i1 > 0) + for (i = ip1, j = 0; i < L_SUBFR; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip1, j = 0; i < L_SUBFR; i++, j++) + y[i] = sub (y[i], h[j]); + + if (i2 > 0) + for (i = ip2, j = 0; i < L_SUBFR; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip2, j = 0; i < L_SUBFR; i++, j++) + y[i] = sub (y[i], h[j]); + + if (i3 > 0) + for (i = ip3, j = 0; i < L_SUBFR; i++, j++) + y[i] = add (y[i], h[j]); + else + for (i = ip3, j = 0; i < L_SUBFR; i++, j++) + y[i] = sub (y[i], h[j]); + + /* find codebook index; 17-bit address */ + + i = 0; + if (i0 > 0) + i = add (i, 1); + if (i1 > 0) + i = add (i, 2); + if (i2 > 0) + i = add (i, 4); + if (i3 > 0) + i = add (i, 8); + *sign = i; + + ip0 = mult (ip0, 6554); /* ip0/5 */ + ip1 = mult (ip1, 6554); /* ip1/5 */ + ip2 = mult (ip2, 6554); /* ip2/5 */ + i = mult (ip3, 6554); /* ip3/5 */ + j = add (i, shl (i, 2)); /* j = i*5 */ + j = sub (ip3, add (j, 3)); /* j= ip3%5 -3 */ + ip3 = add (shl (i, 1), j); + + i = add (ip0, shl (ip1, 3)); + i = add (i, shl (ip2, 6)); + i = add (i, shl (ip3, 9)); + + return i; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/basic_op.c asterisk-1.2.1/codecs/g729a_v11/basic_op.c --- asterisk-1.2.1.ori/codecs/g729a_v11/basic_op.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/basic_op.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,2013 @@ + +/* + * + * Basics operators. + * +*/ + +/* + * + * Include-Files + * +*/ + +#include +#include +#include "typedef.h" +#include "basic_op.h" + + +/* + * + * Function Name : sature + * + * Purpose : + * + * Limit the 32 bit input to the range of a 16 bit word. + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sature (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 > 0X00007fffL) { + var_out = MAX_16; + } + else if (L_var1 < (Word32) 0xffff8000L) { + var_out = MIN_16; + } + else { + var_out = extract_l (L_var1); + } + + return (var_out); +} + + +/* + * + * Function Name : sature + * + * Purpose : + * + * Limit the 32 bit input to the range of a 16 bit word. + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sature_o (Word32 L_var1, Flag *Overflow) +{ + Word16 var_out; + + if (L_var1 > 0X00007fffL) { + *Overflow = 1; + var_out = MAX_16; + } + else if (L_var1 < (Word32) 0xffff8000L) { + *Overflow = 1; + var_out = MIN_16; + } + else { + *Overflow = 0; + var_out = extract_l (L_var1); + } + + return (var_out); +} + +/* + * + * Function Name : add + * + * Purpose : + * + * Performs the addition (var1+var2) with overflow control and saturation; + * the 16 bit result is set at +32767 when overflow occurs or at -32768 + * when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +add (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_somme; + + L_somme = (Word32) var1 + var2; + var_out = sature (L_somme); + return (var_out); +} + +/* + * + * Function Name : sub + * + * Purpose : + * + * Performs the subtraction (var1+var2) with overflow control and satu- + * ration; the 16 bit result is set at +32767 when overflow occurs or at + * -32768 when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sub (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_diff; + + L_diff = (Word32) var1 - var2; + var_out = sature (L_diff); + return (var_out); +} + +/* + * + * Function Name : add_o + * + * Purpose : + * + * Performs the addition (var1+var2) with overflow control and saturation; + * the 16 bit result is set at +32767 when overflow occurs or at -32768 + * when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +add_o (Word16 var1, Word16 var2, Flag *Overflow) +{ + Word16 var_out; + Word32 L_somme; + + L_somme = (Word32) var1 + var2; + var_out = sature_o (L_somme, Overflow); + return (var_out); +} + +/* + * + * Function Name : sub_o + * + * Purpose : + * + * Performs the subtraction (var1+var2) with overflow control and satu- + * ration; the 16 bit result is set at +32767 when overflow occurs or at + * -32768 when underflow occurs. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +sub_o (Word16 var1, Word16 var2, Flag *Overflow) +{ + Word16 var_out; + Word32 L_diff; + + L_diff = (Word32) var1 - var2; + var_out = sature_o (L_diff, Overflow); + return (var_out); +} + +/* + * + * Function Name : abs_s + * + * Purpose : + * + * Absolute value of var1; abs_s(-32768) = 32767. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +abs_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == (Word16) 0X8000) { + var_out = MAX_16; + } + else { + if (var1 < 0) { + var_out = -var1; + } + else { + var_out = var1; + } + } + return (var_out); +} + +/* + * + * Function Name : shl + * + * Purpose : + * + * Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill + * the var2 LSB of the result. If var2 is negative, arithmetically shift + * var1 right by -var2 with sign extension. Saturate the result in case of + * underflows or overflows. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +shl (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 resultat; + + if (var2 < 0) { + var_out = shr (var1, -var2); + } + else { + resultat = (Word32) var1 *((Word32) 1 << var2); + if ((var2 > 15 && var1 != 0) + || (resultat != (Word32) ((Word16) resultat))) { + var_out = (var1 > 0) ? MAX_16 : MIN_16; + } + else { + var_out = extract_l (resultat); + } + } + return (var_out); +} + +/* + * + * Function Name : shr + * + * Purpose : + * + * Arithmetically shift the 16 bit input var1 right var2 positions with + * sign extension. If var2 is negative, arithmetically shift var1 left by + * -var2 with sign extension. Saturate the result in case of underflows or + * overflows. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +shr (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 < 0) { + var_out = shl (var1, -var2); + } + else { + if (var2 >= 15) { + var_out = (var1 < 0) ? (Word16) (-1) : (Word16) 0; + } + else { + if (var1 < 0) { + var_out = ~((~var1) >> var2); + } + else { + var_out = var1 >> var2; + } + } + } + + return (var_out); +} + +/* + * + * Function Name : mult + * + * Purpose : + * + * Performs the multiplication of var1 by var2 and gives a 16 bit result + * which is scaled i.e.: + * mult(var1,var2) = shr((var1 times var2),15) and + * mult(-32768,-32768) = 32767. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +mult (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_produit; + + L_produit = (Word32) var1 *(Word32) var2; + + L_produit = (L_produit & (Word32) 0xffff8000L) >> 15; + + if (L_produit & (Word32) 0x00010000L) + L_produit = L_produit | (Word32) 0xffff0000L; + + var_out = sature (L_produit); + return (var_out); +} + + +/* + * + * Function Name : L_mult + * + * Purpose : + * + * L_mult is the 32 bit result of the multiplication of var1 times var2 + * with one shift left i.e.: + * L_mult(var1,var2) = shl((var1 times var2),1) and + * L_mult(-32768,-32768) = 2147483647. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mult (Word16 var1, Word16 var2) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 *(Word32) var2; + if (L_var_out != (Word32) 0x40000000L) { + L_var_out *= 2; + } + else { + L_var_out = MAX_32; + } + + return (L_var_out); +} + +/* + * + * Function Name : L_mult_o + * + * Purpose : + * + * L_mult is the 32 bit result of the multiplication of var1 times var2 + * with one shift left i.e.: + * L_mult(var1,var2) = shl((var1 times var2),1) and + * L_mult(-32768,-32768) = 2147483647. + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mult_o (Word16 var1, Word16 var2, Flag *Overflow) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 *(Word32) var2; + if (L_var_out != (Word32) 0x40000000L) { + L_var_out *= 2; + } + else { + *Overflow = 1; + L_var_out = MAX_32; + } + + return (L_var_out); +} + +/* + * + * Function Name : negate + * + * Purpose : + * + * Negate var1 with saturation, saturate in the case where input is -32768: + * negate(var1) = sub(0,var1). + * + * Complexity weight : 1 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +negate (Word16 var1) +{ + Word16 var_out; + + var_out = (var1 == MIN_16) ? MAX_16 : -var1; + return (var_out); +} + + +/* + * + * Function Name : extract_h + * + * Purpose : + * + * Return the 16 MSB of L_var1. + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +extract_h (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) (L_var1 >> 16); + return (var_out); +} + +/* + * + * Function Name : extract_l + * + * Purpose : + * + * Return the 16 LSB of L_var1. + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +extract_l (Word32 L_var1) +{ + Word16 var_out; + + var_out = (Word16) L_var1; + return (var_out); +} + + +/* + * + * Function Name : wround + * + * Purpose : + * + * Round the lower 16 bits of the 32 bit input number into its MS 16 bits + * with saturation. Shift the resulting bits right by 16 and return the 16 + * bit number: + * wround(L_var1) = extract_h(L_add(L_var1,32768)) + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +wround (Word32 L_var1) +{ + Word16 var_out; + Word32 L_arrondi; + + L_arrondi = L_add (L_var1, (Word32) 0x00008000); + var_out = extract_h (L_arrondi); + return (var_out); +} + +/* + * + * Function Name : wround_o + * + * Purpose : + * + * Round the lower 16 bits of the 32 bit input number into its MS 16 bits + * with saturation. Shift the resulting bits right by 16 and return the 16 + * bit number: + * wround(L_var1) = extract_h(L_add(L_var1,32768)) + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32 ) whose value falls in the + * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +wround_o (Word32 L_var1, Flag *Overflow) +{ + Word16 var_out; + Word32 L_arrondi; + + L_arrondi = L_add_o (L_var1, (Word32) 0x00008000, Overflow); + var_out = extract_h (L_arrondi); + return (var_out); +} + + +/* + * + * Function Name : L_mac + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + * result to L_var3 with saturation, return a 32 bit result: + * L_mac(L_var3,var1,var2) = L_add(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mac (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult (var1, var2); + L_var_out = L_add (L_var3, L_produit); + return (L_var_out); +} + + +/* + * + * Function Name : L_mac_o + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + * result to L_var3 with saturation, return a 32 bit result: + * L_mac(L_var3,var1,var2) = L_add(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_mac_o (Word32 L_var3, Word16 var1, Word16 var2, Flag* Overflow) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult_o (var1, var2, Overflow); + L_var_out = L_add_o (L_var3, L_produit, Overflow); + return (L_var_out); +} + +/* + * + * Function Name : L_msu + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Subtract the 32 + * bit result to L_var3 with saturation, return a 32 bit result: + * L_msu(L_var3,var1,var2) = L_sub(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_msu (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult (var1, var2); + L_var_out = L_sub (L_var3, L_produit); + return (L_var_out); +} + +/* + * + * Function Name : L_msu_o + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Subtract the 32 + * bit result to L_var3 with saturation, return a 32 bit result: + * L_msu(L_var3,var1,var2) = L_sub(L_var3,(L_mult(var1,var2)). + * + * Complexity weight : 1 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_msu_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow) +{ + Word32 L_var_out; + Word32 L_produit; + + L_produit = L_mult_o (var1, var2, Overflow); + L_var_out = L_sub_o (L_var3, L_produit, Overflow); + return (L_var_out); +} + +/* + * + * Function Name : L_add + * + * Purpose : + * + * 32 bits addition of the two 32 bits variables (L_var1+L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_add (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) == 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_sub + * + * Purpose : + * + * 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_sub (Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_add_o + * + * Purpose : + * + * 32 bits addition of the two 32 bits variables (L_var1+L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_add_o (Word32 L_var1, Word32 L_var2, Flag *Overflow) +{ + Word32 L_var_out; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) == 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32; + *Overflow = 1; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_sub_o + * + * Purpose : + * + * 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with + * overflow control and saturation; the result is set at +214783647 when + * overflow occurs or at -214783648 when underflow occurs. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * L_var2 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_sub_o (Word32 L_var1, Word32 L_var2, Flag *Overflow) +{ + Word32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0) { + if ((L_var_out ^ L_var1) & MIN_32) { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + *Overflow = 1; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_negate + * + * Purpose : + * + * Negate the 32 bit variable L_var1 with saturation; saturate in the case + * where input is -2147483648 (0x8000 0000). + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_negate (Word32 L_var1) +{ + Word32 L_var_out; + + L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1; + return (L_var_out); +} + +/* + * + * Function Name : mult_r + * + * Purpose : + * + * Same as mult with rounding, i.e.: + * mult_r(var1,var2) = shr(((var1*var2) + 16384),15) and + * mult_r(-32768,-32768) = 32767. + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +mult_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + Word32 L_produit_arr; + + L_produit_arr = (Word32) var1 *(Word32) var2; /* product */ + L_produit_arr += (Word32) 0x00004000; /* round */ + L_produit_arr &= (Word32) 0xffff8000L; + L_produit_arr >>= 15; /* shift */ + + if (L_produit_arr & (Word32) 0x00010000L) { /* sign extend when necessary */ + L_produit_arr |= (Word32) 0xffff0000L; + } + + var_out = sature (L_produit_arr); + return (var_out); +} + +/* + * + * Function Name : L_shl + * + * Purpose : + * + * Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero + * fill the var2 LSB of the result. If var2 is negative, L_var1 right by + * -var2 arithmetically shift with sign extension. Saturate the result in + * case of underflows or overflows. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shl (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + /* initialization used only to suppress Microsoft Visual C++ warnings */ + L_var_out = 0L; + + if (var2 <= 0) { + L_var_out = L_shr (L_var1, -var2); + } + else { + for (; var2 > 0; var2--) { + if (L_var1 > (Word32) 0X3fffffffL) { + L_var_out = MAX_32; + break; + } + else { + if (L_var1 < (Word32) 0xc0000000L) { + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2; + L_var_out = L_var1; + } + } + return (L_var_out); +} + + +/* + * + * Function Name : L_shl_o + * + * Purpose : + * + * Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero + * fill the var2 LSB of the result. If var2 is negative, L_var1 right by + * -var2 arithmetically shift with sign extension. Saturate the result in + * case of underflows or overflows. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shl_o (Word32 L_var1, Word16 var2, Flag *Overflow) +{ + Word32 L_var_out; + + /* initialization used only to suppress Microsoft Visual C++ warnings */ + L_var_out = 0L; + + if (var2 <= 0) { + L_var_out = L_shr (L_var1, -var2); + } + else { + for (; var2 > 0; var2--) { + if (L_var1 > (Word32) 0X3fffffffL) { + *Overflow = 1; + L_var_out = MAX_32; + break; + } + else { + if (L_var1 < (Word32) 0xc0000000L) { + *Overflow = 1; + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2; + L_var_out = L_var1; + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_shr + * + * Purpose : + * + * Arithmetically shift the 32 bit input L_var1 right var2 positions with + * sign extension. If var2 is negative, arithmetically shift L_var1 left + * by -var2 and zero fill the var2 LSB of the result. Saturate the result + * in case of underflows or overflows. + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var1 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shr (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 < 0) { + L_var_out = L_shl (L_var1, -var2); + } + else { + if (var2 >= 31) { + L_var_out = (L_var1 < 0L) ? -1 : 0; + } + else { + if (L_var1 < 0) { + L_var_out = ~((~L_var1) >> var2); + } + else { + L_var_out = L_var1 >> var2; + } + } + } + return (L_var_out); +} + +/* + * + * Function Name : shr_r + * + * Purpose : + * + * Same as shr(var1,var2) but with rounding. Saturate the result in case of + * underflows or overflows : + * If var2 is greater than zero : + * shr_r(var1,var2) = shr(add(var1,2**(var2-1)),var2) + * If var2 is less than zero : + * shr_r(var1,var2) = shr(var1,var2). + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word16 +shr_r (Word16 var1, Word16 var2) +{ + Word16 var_out; + + if (var2 > 15) { + var_out = 0; + } + else { + var_out = shr (var1, var2); + + if (var2 > 0) { + if ((var1 & ((Word16) 1 << (var2 - 1))) != 0) { + var_out++; + } + } + } + return (var_out); +} + +/* + * + * Function Name : mac_r + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + * result to L_var3 with saturation. Round the LS 16 bits of the result + * into the MS 16 bits with saturation and shift the result right by 16. + * Return a 16 bit result. + * mac_r(L_var3,var1,var2) = wround(L_mac(Lvar3,var1,var2)) + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. + * +*/ + +Word16 +mac_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_mac (L_var3, var1, var2); + L_var3 = L_add (L_var3, (Word32) 0x00008000); + var_out = extract_h (L_var3); + return (var_out); +} + + +/* + * + * Function Name : msu_r + * + * Purpose : + * + * Multiply var1 by var2 and shift the result left by 1. Subtract the 32 + * bit result to L_var3 with saturation. Round the LS 16 bits of the res- + * ult into the MS 16 bits with saturation and shift the result right by + * 16. Return a 16 bit result. + * msu_r(L_var3,var1,var2) = wround(L_msu(Lvar3,var1,var2)) + * + * Complexity weight : 2 + * + * Inputs : + * + * L_var3 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. + * +*/ + +Word16 +msu_r (Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_msu (L_var3, var1, var2); + L_var3 = L_add (L_var3, (Word32) 0x00008000); + var_out = extract_h (L_var3); + return (var_out); +} + + + +/* + * + * Function Name : L_deposit_h + * + * Purpose : + * + * Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The + * 16 LS bits of the output are zeroed. + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var_out <= 0x7fff 0000. + * +*/ + +Word32 +L_deposit_h (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1 << 16; + return (L_var_out); +} + +/* + * + * Function Name : L_deposit_l + * + * Purpose : + * + * Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The + * 16 MS bits of the output are sign extended. + * + * Complexity weight : 2 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0xFFFF 8000 <= var_out <= 0x0000 7fff. + * +*/ + +Word32 +L_deposit_l (Word16 var1) +{ + Word32 L_var_out; + + L_var_out = (Word32) var1; + return (L_var_out); +} + +/* + * + * Function Name : L_shr_r + * + * Purpose : + * + * Same as L_shr(L_var1,var2)but with rounding. Saturate the result in case + * of underflows or overflows : + * If var2 is greater than zero : + * L_shr_r(var1,var2) = L_shr(L_add(L_var1,2**(var2-1)),var2) + * If var2 is less than zero : + * L_shr_r(var1,var2) = L_shr(L_var1,var2). + * + * Complexity weight : 3 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var1 <= 0x7fff ffff. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_shr_r (Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 > 31) { + L_var_out = 0; + } + else { + L_var_out = L_shr (L_var1, var2); + if (var2 > 0) { + if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0) { + L_var_out++; + } + } + } + return (L_var_out); +} + +/* + * + * Function Name : L_abs + * + * Purpose : + * + * Absolute value of L_var1; Saturate in case where the input is + * -214783648 + * + * Complexity weight : 3 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * L_var_out + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x7fff ffff. + * +*/ + +Word32 +L_abs (Word32 L_var1) +{ + Word32 L_var_out; + + if (L_var1 == MIN_32) { + L_var_out = MAX_32; + } + else { + if (L_var1 < 0) { + L_var_out = -L_var1; + } + else { + L_var_out = L_var1; + } + } + + return (L_var_out); +} + +/* + * + * Function Name : norm_s + * + * Purpose : + * + * Produces the number of left shift needed to normalize the 16 bit varia- + * ble var1 for positive values on the interval with minimum of 16384 and + * maximum of 32767, and for negative values on the interval with minimum + * of -32768 and maximum of -16384; in order to normalize the result, the + * following operation must be done : + * norm_var1 = shl(var1,norm_s(var1)). + * + * Complexity weight : 15 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0xffff 8000 <= var1 <= 0x0000 7fff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 000f. + * +*/ + +Word16 +norm_s (Word16 var1) +{ + Word16 var_out; + + if (var1 == 0) { + var_out = 0; + } + else { + if (var1 == (Word16) 0xffff) { + var_out = 15; + } + else { + if (var1 < 0) { + var1 = ~var1; + } + + for (var_out = 0; var1 < 0x4000; var_out++) { + var1 <<= 1; + } + } + } + + return (var_out); +} + + +/* + * + * Function Name : div_s + * + * Purpose : + * + * Produces a result which is the fractional integer division of var1 by + * var2; var1 and var2 must be positive and var2 must be greater or equal + * to var1; the result is positive (leading bit equal to 0) and truncated + * to 16 bits. + * If var1 = var2 then div(var1,var2) = 32767. + * + * Complexity weight : 18 + * + * Inputs : + * + * var1 + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var1 <= var2 and var2 != 0. + * + * var2 + * 16 bit short signed integer (Word16) whose value falls in the + * range : var1 <= var2 <= 0x0000 7fff and var2 != 0. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 7fff. + * It's a Q15 value (point between b15 and b14). + * +*/ + +Word16 +div_s (Word16 var1, Word16 var2) +{ + Word16 var_out = 0; + Word16 iteration; + Word32 L_num; + Word32 L_denom; + + if ((var1 > var2) || (var1 < 0) || (var2 < 0)) { + printf ("Division Error var1=%d var2=%d\n", var1, var2); + exit (0); + } + + if (var2 == 0) { + printf ("Division by 0, Fatal error \n"); + exit (0); + } + + if (var1 == 0) { + var_out = 0; + } + else { + if (var1 == var2) { + var_out = MAX_16; + } + else { + L_num = L_deposit_l (var1); + L_denom = L_deposit_l (var2); + + for (iteration = 0; iteration < 15; iteration++) { + var_out <<= 1; + L_num <<= 1; + + if (L_num >= L_denom) { + L_num = L_sub (L_num, L_denom); + var_out = add (var_out, 1); + } + } + } + } + + return (var_out); +} + + +/* + * + * Function Name : norm_l + * + * Purpose : + * + * Produces the number of left shift needed to normalize the 32 bit varia- + * ble l_var1 for positive values on the interval with minimum of + * 1073741824 and maximum of 2147483647, and for negative values on the in- + * terval with minimum of -2147483648 and maximum of -1073741824; in order + * to normalize the result, the following operation must be done : + * norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). + * + * Complexity weight : 30 + * + * Inputs : + * + * L_var1 + * 32 bit long signed integer (Word32) whose value falls in the + * range : 0x8000 0000 <= var1 <= 0x7fff ffff. + * + * Outputs : + * + * none + * + * Return Value : + * + * var_out + * 16 bit short signed integer (Word16) whose value falls in the + * range : 0x0000 0000 <= var_out <= 0x0000 001f. + * +*/ + +Word16 +norm_l (Word32 L_var1) +{ + Word16 var_out; + + if (L_var1 == 0) { + var_out = 0; + } + else { + if (L_var1 == (Word32) 0xffffffffL) { + var_out = 31; + } + else { + if (L_var1 < 0) { + L_var1 = ~L_var1; + } + + for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++) { + L_var1 <<= 1; + } + } + } + + return (var_out); +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/basic_op.h asterisk-1.2.1/codecs/g729a_v11/basic_op.h --- asterisk-1.2.1.ori/codecs/g729a_v11/basic_op.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/basic_op.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,46 @@ +#define MAX_32 (Word32)0x7fffffffL +#define MIN_32 (Word32)0x80000000L + +#define MAX_16 (Word16)0x7fff +#define MIN_16 (Word16)0x8000 + +Word16 sature (Word32 L_var1); /* Limit to 16 bits, 1 */ +Word16 sature_o (Word32 L_var1, Flag *Overflow); /* Limit to 16 bits, 1 */ +Word16 add (Word16 var1, Word16 var2); /* Short add, 1 */ +Word16 sub (Word16 var1, Word16 var2); /* Short sub, 1 */ +Word16 add_o (Word16 var1, Word16 var2, Flag *Overflow); /* Short add, 1 */ +Word16 sub_o (Word16 var1, Word16 var2, Flag *Overflow); /* Short sub, 1 */ +Word16 abs_s (Word16 var1); /* Short abs, 1 */ +Word16 shl (Word16 var1, Word16 var2); /* Short shift left, 1 */ +Word16 shr (Word16 var1, Word16 var2); /* Short shift right, 1 */ +Word16 mult (Word16 var1, Word16 var2); /* Short mult, 1 */ +Word32 L_mult (Word16 var1, Word16 var2); /* Long mult, 1 */ +Word32 L_mult_o (Word16 var1, Word16 var2, Flag *Overflow); /* Long mult, 1 */ +Word16 negate (Word16 var1); /* Short negate, 1 */ +Word16 extract_h (Word32 L_var1); /* Extract high, 1 */ +Word16 extract_l (Word32 L_var1); /* Extract low, 1 */ +Word16 wround (Word32 L_var1); /* Round, 1 */ +Word16 wround_o (Word32 L_var1, Flag *Overflow); /* Round, 1 */ +Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); /* Mac, 1 */ +Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); /* Msu, 1 */ +Word32 L_mac_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow); /* Mac, 1 */ +Word32 L_msu_o (Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow); /* Msu, 1 */ +Word32 L_add (Word32 L_var1, Word32 L_var2); /* Long add, 2 */ +Word32 L_sub (Word32 L_var1, Word32 L_var2); /* Long sub, 2 */ +Word32 L_add_o (Word32 L_var1, Word32 L_var2, Flag *Overflow); /* Long add, 2 */ +Word32 L_sub_o (Word32 L_var1, Word32 L_var2, Flag *Overflow); /* Long sub, 2 */ +Word32 L_negate (Word32 L_var1); /* Long negate, 2 */ +Word16 mult_r (Word16 var1, Word16 var2); /* Mult with round, 2 */ +Word32 L_shl (Word32 L_var1, Word16 var2); /* Long shift left, 2 */ +Word32 L_shl_o (Word32 L_var1, Word16 var2, Flag *Overflow); /* Long shift left, 2 */ +Word32 L_shr (Word32 L_var1, Word16 var2); /* Long shift right, 2 */ +Word16 shr_r (Word16 var1, Word16 var2); /* Shift right with round, 2 */ +Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); /* Mac with rounding, 2 */ +Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); /* Msu with rounding, 2 */ +Word32 L_deposit_h (Word16 var1); /* 16 bit var1 -> MSB, 2 */ +Word32 L_deposit_l (Word16 var1); /* 16 bit var1 -> LSB, 2 */ +Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with round, 3 */ +Word32 L_abs (Word32 L_var1); /* Long abs, 3 */ +Word16 norm_s (Word16 var1); /* Short norm, 15 */ +Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */ +Word16 norm_l (Word32 L_var1); /* Long norm, 30 */ diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/cod_ld8a.c asterisk-1.2.1/codecs/g729a_v11/cod_ld8a.c --- asterisk-1.2.1.ori/codecs/g729a_v11/cod_ld8a.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/cod_ld8a.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,430 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-----------------------------------------------------------------* + * Functions Coder_ld8a and Init_Coder_ld8a * + * ~~~~~~~~~~ ~~~~~~~~~~~~~~~ * + * * + * Init_Coder_ld8a(void); * + * * + * ->Initialization of variables for the coder section. * + * * + * * + * Coder_ld8a(Word16 ana[]); * + * * + * ->Main coder function. * + * * + * * + * Input: * + * * + * 80 speech data should have beee copy to vector new_speech[]. * + * This vector is global and is declared in this function. * + * * + * Ouputs: * + * * + * ana[] ->analysis parameters. * + * * + *-----------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" +#include "util.h" +#include "qua_lsp.h" +#include "taming.h" +#include "qua_gain.h" + +/*-----------------------------------------------------------* + * Coder constant parameters (defined in "ld8a.h") * + *-----------------------------------------------------------* + * L_WINDOW : LPC analysis window size. * + * L_NEXT : Samples of next frame needed for autocor. * + * L_FRAME : Frame size. * + * L_SUBFR : Sub-frame size. * + * M : LPC order. * + * MP1 : LPC order+1 * + * L_TOTAL : Total size of speech buffer. * + * PIT_MIN : Minimum pitch lag. * + * PIT_MAX : Maximum pitch lag. * + * L_INTERPOL : Length of filter for interpolation * + *-----------------------------------------------------------*/ + +/*-----------------------------------------------------------------* + * Function Init_Coder_ld8a * + * ~~~~~~~~~~~~~~~ * + * * + * Init_Coder_ld8a(void); * + * * + * ->Initialization of variables for the coder section. * + * - initialize pointers to speech buffer * + * - initialize pointers * + * - set vectors to zero * + * * + *-----------------------------------------------------------------*/ + +CodState* +Init_Coder_ld8a (void) +{ + CodState *coder; + + coder = (CodState *) malloc (sizeof (CodState)); + + /*----------------------------------------------------------------------* + * Initialize pointers to speech vector. * + * * + * * + * |--------------------|-------------|-------------|------------| * + * previous speech sf1 sf2 L_NEXT * + * * + * <---------------- Total speech vector (L_TOTAL) -----------> * + * <---------------- LPC analysis window (L_WINDOW) -----------> * + * | <-- present frame (L_FRAME) --> * + * old_speech | <-- new speech (L_FRAME) --> * + * p_window | | * + * speech | * + * new_speech * + *-----------------------------------------------------------------------*/ + + coder->new_speech = coder->old_speech + L_TOTAL - L_FRAME; /* New speech */ + coder->speech = coder->new_speech - L_NEXT; /* Present frame */ + coder->p_window = coder->old_speech + L_TOTAL - L_WINDOW; /* For LPC window */ + + /* Initialize pointers */ + + coder->wsp = coder->old_wsp + PIT_MAX; + coder->exc = coder->old_exc + PIT_MAX + L_INTERPOL; + + /* Static vectors to zero */ + + Set_zero (coder->old_speech, L_TOTAL); + Set_zero (coder->old_exc, PIT_MAX + L_INTERPOL); + Set_zero (coder->old_wsp, PIT_MAX); + Set_zero (coder->mem_w, M); + Set_zero (coder->mem_w0, M); + Set_zero (coder->mem_zero, M); + coder->sharp = SHARPMIN; + + /* Initialize lsp_old_q[] */ + Copy (lsp_old_init, coder->lsp_old, M); + Copy (lsp_old_init, coder->lsp_old_q, M); + + Lsp_encw_reset (coder); + Init_exc_err (coder); + + Copy (past_qua_en_init, coder->past_qua_en, 4); + + Set_zero (coder->old_A, M + 1); + coder->old_A [0] = 4096; + Set_zero (coder->old_rc, 2); + + return coder; +} + +/*-----------------------------------------------------------------* + * Functions Coder_ld8a * + * ~~~~~~~~~~ * + * Coder_ld8a(Word16 ana[]); * + * * + * ->Main coder function. * + * * + * * + * Input: * + * * + * 80 speech data should have beee copy to vector new_speech[]. * + * This vector is global and is declared in this function. * + * * + * Ouputs: * + * * + * ana[] ->analysis parameters. * + * * + *-----------------------------------------------------------------*/ + +void +Coder_ld8a (CodState *coder, Word16 ana[]) +{ + + /* LPC analysis */ + + Word16 Aq_t[(MP1) * 2]; /* A(z) quantized for the 2 subframes */ + Word16 Ap_t[(MP1) * 2]; /* A(z/gamma) for the 2 subframes */ + Word16 *Aq, *Ap; /* Pointer on Aq_t and Ap_t */ + + /* Other vectors */ + + Word16 h1[L_SUBFR]; /* Impulse response h1[] */ + Word16 xn[L_SUBFR]; /* Target vector for pitch search */ + Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ + Word16 code[L_SUBFR]; /* Fixed codebook excitation */ + Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ + Word16 y2[L_SUBFR]; /* Filtered fixed codebook excitation */ + Word16 g_coeff[4]; /* Correlations between xn & y1 */ + + Word16 g_coeff_cs[5]; + Word16 exp_g_coeff_cs[5]; /* Correlations between xn, y1, & y2 + , -2, + , -2, 2 */ + + /* Scalars */ + + Word16 i, j, k, i_subfr; + Word16 T_op, T0, T0_min, T0_max, T0_frac; + Word16 gain_pit, gain_code, index; + Word16 temp, taming; + Word32 L_temp; + +/*------------------------------------------------------------------------* + * - Perform LPC analysis: * + * * autocorrelation + lag windowing * + * * Levinson-durbin algorithm to find a[] * + * * convert a[] to lsp[] * + * * quantize and code the LSPs * + * * find the interpolated LSPs and convert to a[] for the 2 * + * subframes (both quantized and unquantized) * + *------------------------------------------------------------------------*/ + { + /* Temporary vectors */ + Word16 r_l[MP1], r_h[MP1]; /* Autocorrelations low and hi */ + Word16 rc[M]; /* Reflection coefficients. */ + Word16 lsp_new[M], lsp_new_q[M]; /* LSPs at 2th subframe */ + + /* LP analysis */ + + Autocorr (coder->p_window, M, r_h, r_l); /* Autocorrelations */ + Lag_window (M, r_h, r_l); /* Lag windowing */ + Levinson (coder, r_h, r_l, Ap_t, rc); /* Levinson Durbin */ + Az_lsp (Ap_t, lsp_new, coder->lsp_old); /* From A(z) to lsp */ + + /* LSP quantization */ + + Qua_lsp (coder, lsp_new, lsp_new_q, ana); + ana += 2; /* Advance analysis parameters pointer */ + + /*--------------------------------------------------------------------* + * Find interpolated LPC parameters in all subframes * + * The interpolated parameters are in array Aq_t[]. * + *--------------------------------------------------------------------*/ + + Int_qlpc (coder->lsp_old_q, lsp_new_q, Aq_t); + + /* Compute A(z/gamma) */ + + Weight_Az (&Aq_t[0], GAMMA1, M, &Ap_t[0]); + Weight_Az (&Aq_t[MP1], GAMMA1, M, &Ap_t[MP1]); + + /* update the LSPs for the next frame */ + + Copy (lsp_new, coder->lsp_old, M); + Copy (lsp_new_q, coder->lsp_old_q, M); + } + + /*----------------------------------------------------------------------* + * - Find the weighted input speech w_sp[] for the whole speech frame * + * - Find the open-loop pitch delay * + *----------------------------------------------------------------------*/ + + Residu (&Aq_t[0], &coder->speech[0], &coder->exc[0], L_SUBFR); + Residu (&Aq_t[MP1], &coder->speech[L_SUBFR], &coder->exc[L_SUBFR], L_SUBFR); + + { + Word16 Ap1[MP1]; + + Ap = Ap_t; + Ap1[0] = 4096; + for (i = 1; i <= M; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */ + Ap1[i] = sub (Ap[i], mult (Ap[i - 1], 22938)); + Syn_filt (Ap1, &coder->exc[0], &coder->wsp[0], L_SUBFR, coder->mem_w, 1, NULL); + + Ap += MP1; + for (i = 1; i <= M; i++) /* Ap1[i] = Ap[i] - 0.7 * Ap[i-1]; */ + Ap1[i] = sub (Ap[i], mult (Ap[i - 1], 22938)); + Syn_filt (Ap1, &coder->exc[L_SUBFR], &coder->wsp[L_SUBFR], L_SUBFR, coder->mem_w, 1, NULL); + } + + /* Find open loop pitch lag */ + + T_op = Pitch_ol_fast (coder->wsp, PIT_MAX, L_FRAME); + + /* Range for closed loop pitch search in 1st subframe */ + + T0_min = sub (T_op, 3); + if (sub (T0_min, PIT_MIN) < 0) { + T0_min = PIT_MIN; + } + + T0_max = add (T0_min, 6); + if (sub (T0_max, PIT_MAX) > 0) { + T0_max = PIT_MAX; + T0_min = sub (T0_max, 6); + } + + + /*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * To find the pitch and innovation parameters. The subframe size is * + * L_SUBFR and the loop is repeated 2 times. * + * - find the weighted LPC coefficients * + * - find the LPC residual signal res[] * + * - compute the target signal for pitch search * + * - compute impulse response of weighted synthesis filter (h1[]) * + * - find the closed-loop pitch parameters * + * - encode the pitch delay * + * - find target vector for codebook search * + * - codebook search * + * - VQ of pitch and codebook gains * + * - update states of weighting filter * + *------------------------------------------------------------------------*/ + + Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ + Ap = Ap_t; /* pointer to weighted LPC coefficients */ + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { + + /*---------------------------------------------------------------* + * Compute impulse response, h1[], of weighted synthesis filter * + *---------------------------------------------------------------*/ + + h1[0] = 4096; + Set_zero (&h1[1], L_SUBFR - 1); + Syn_filt (Ap, h1, h1, L_SUBFR, &h1[1], 0, NULL); + + /*----------------------------------------------------------------------* + * Find the target vector for pitch search: * + *----------------------------------------------------------------------*/ + + Syn_filt (Ap, &coder->exc[i_subfr], xn, L_SUBFR, coder->mem_w0, 0, NULL); + + /*---------------------------------------------------------------------* + * Closed-loop fractional pitch search * + *---------------------------------------------------------------------*/ + + T0 = Pitch_fr3_fast (&coder->exc[i_subfr], xn, h1, L_SUBFR, T0_min, T0_max, + i_subfr, &T0_frac); + + index = + Enc_lag3 (T0, T0_frac, &T0_min, &T0_max, PIT_MIN, PIT_MAX, i_subfr); + + *ana++ = index; + + if (i_subfr == 0) { + *ana++ = Parity_Pitch (index); + } + + /*-----------------------------------------------------------------* + * - find filtered pitch exc * + * - compute pitch gain and limit between 0 and 1.2 * + * - update target vector for codebook search * + *-----------------------------------------------------------------*/ + + Syn_filt (Ap, &coder->exc[i_subfr], y1, L_SUBFR, coder->mem_zero, 0, NULL); + + gain_pit = G_pitch (xn, y1, g_coeff, L_SUBFR); + + /* clip pitch gain if taming is necessary */ + + taming = test_err (coder, T0, T0_frac); + + if (taming == 1) { + if (sub (gain_pit, GPCLIP) > 0) { + gain_pit = GPCLIP; + } + } + + /* xn2[i] = xn[i] - y1[i] * gain_pit */ + + for (i = 0; i < L_SUBFR; i++) { + L_temp = L_mult (y1[i], gain_pit); + L_temp = L_shl (L_temp, 1); /* gain_pit in Q14 */ + xn2[i] = sub (xn[i], extract_h (L_temp)); + } + + + /*-----------------------------------------------------* + * - Innovative codebook search. * + *-----------------------------------------------------*/ + + index = ACELP_Code_A (xn2, h1, T0, coder->sharp, code, y2, &i); + + *ana++ = index; /* Positions index */ + *ana++ = i; /* Signs index */ + + + /*-----------------------------------------------------* + * - Quantization of gains. * + *-----------------------------------------------------*/ + + g_coeff_cs[0] = g_coeff[0]; /* */ + exp_g_coeff_cs[0] = negate (g_coeff[1]); /* Q-Format:XXX -> JPN */ + g_coeff_cs[1] = negate (g_coeff[2]); /* (xn,y1) -> -2 */ + exp_g_coeff_cs[1] = negate (add (g_coeff[3], 1)); /* Q-Format:XXX -> JPN */ + + Corr_xy2 (xn, y1, y2, g_coeff_cs, exp_g_coeff_cs); /* Q0 Q0 Q12 ^Qx ^Q0 */ + /* g_coeff_cs[3]:exp_g_coeff_cs[3] = */ + /* g_coeff_cs[4]:exp_g_coeff_cs[4] = -2 */ + /* g_coeff_cs[5]:exp_g_coeff_cs[5] = 2 */ + + *ana++ = Qua_gain (coder, code, g_coeff_cs, exp_g_coeff_cs, + L_SUBFR, &gain_pit, &gain_code, taming); + + + /*------------------------------------------------------------* + * - Update pitch sharpening "sharp" with quantized gain_pit * + *------------------------------------------------------------*/ + + coder->sharp = gain_pit; + if (sub (coder->sharp, SHARPMAX) > 0) { + coder->sharp = SHARPMAX; + } + if (sub (coder->sharp, SHARPMIN) < 0) { + coder->sharp = SHARPMIN; + } + + /*------------------------------------------------------* + * - Find the total excitation * + * - update filters memories for finding the target * + * vector in the next subframe * + *------------------------------------------------------*/ + + for (i = 0; i < L_SUBFR; i++) { + /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */ + /* exc[i] in Q0 gain_pit in Q14 */ + /* code[i] in Q13 gain_cod in Q1 */ + + L_temp = L_mult (coder->exc[i + i_subfr], gain_pit); + L_temp = L_mac (L_temp, code[i], gain_code); + L_temp = L_shl (L_temp, 1); + coder->exc[i + i_subfr] = wround (L_temp); + } + + update_exc_err (coder, gain_pit, T0); + + for (i = L_SUBFR - M, j = 0; i < L_SUBFR; i++, j++) { + temp = extract_h (L_shl (L_mult (y1[i], gain_pit), 1)); + k = extract_h (L_shl (L_mult (y2[i], gain_code), 2)); + coder->mem_w0[j] = sub (xn[i], add (temp, k)); + } + + Aq += MP1; /* interpolated LPC parameters for next subframe */ + Ap += MP1; + + } + + /*--------------------------------------------------* + * Update signal for next frame. * + * -> shift to the left by L_FRAME: * + * speech[], wsp[] and exc[] * + *--------------------------------------------------*/ + + Copy (&coder->old_speech[L_FRAME], &coder->old_speech[0], L_TOTAL - L_FRAME); + Copy (&coder->old_wsp[L_FRAME], &coder->old_wsp[0], PIT_MAX); + Copy (&coder->old_exc[L_FRAME], &coder->old_exc[0], PIT_MAX + L_INTERPOL); + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/cor_func.c asterisk-1.2.1/codecs/g729a_v11/cor_func.c --- asterisk-1.2.1.ori/codecs/g729a_v11/cor_func.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/cor_func.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,139 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/* Functions Corr_xy2() and Cor_h_x() */ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +/*---------------------------------------------------------------------------* + * Function corr_xy2() * + * ~~~~~~~~~~~~~~~~~~~ * + * Find the correlations between the target xn[], the filtered adaptive * + * codebook excitation y1[], and the filtered 1st codebook innovation y2[]. * + * g_coeff[2]:exp_g_coeff[2] = * + * g_coeff[3]:exp_g_coeff[3] = -2 * + * g_coeff[4]:exp_g_coeff[4] = 2 * + *---------------------------------------------------------------------------*/ + +void +Corr_xy2 (Word16 xn[], /* (i) Q0 :Target vector. */ + Word16 y1[], /* (i) Q0 :Adaptive codebook. */ + Word16 y2[], /* (i) Q12 :Filtered innovative vector. */ + Word16 g_coeff[], /* (o) Q[exp]:Correlations between xn,y1,y2 */ + Word16 exp_g_coeff[] /* (o) :Q-format of g_coeff[] */ + ) +{ + Word16 i, exp; + Word16 exp_y2y2, exp_xny2, exp_y1y2; + Word16 y2y2, xny2, y1y2; + Word32 L_acc; + Word16 scaled_y2[L_SUBFR]; /* Q9 */ + + /*------------------------------------------------------------------* + * Scale down y2[] from Q12 to Q9 to avoid overflow * + *------------------------------------------------------------------*/ + for (i = 0; i < L_SUBFR; i++) { + scaled_y2[i] = shr (y2[i], 3); + } + + /* Compute scalar product */ + L_acc = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_SUBFR; i++) + L_acc = L_mac (L_acc, scaled_y2[i], scaled_y2[i]); /* L_acc:Q19 */ + + exp = norm_l (L_acc); + y2y2 = wround (L_shl (L_acc, exp)); + exp_y2y2 = add (exp, 19 - 16); /* Q[19+exp-16] */ + + g_coeff[2] = y2y2; + exp_g_coeff[2] = exp_y2y2; + + /* Compute scalar product */ + L_acc = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_SUBFR; i++) + L_acc = L_mac (L_acc, xn[i], scaled_y2[i]); /* L_acc:Q10 */ + + exp = norm_l (L_acc); + xny2 = wround (L_shl (L_acc, exp)); + exp_xny2 = add (exp, 10 - 16); /* Q[10+exp-16] */ + + g_coeff[3] = negate (xny2); + exp_g_coeff[3] = sub (exp_xny2, 1); /* -2 */ + + /* Compute scalar product */ + L_acc = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_SUBFR; i++) + L_acc = L_mac (L_acc, y1[i], scaled_y2[i]); /* L_acc:Q10 */ + + exp = norm_l (L_acc); + y1y2 = wround (L_shl (L_acc, exp)); + exp_y1y2 = add (exp, 10 - 16); /* Q[10+exp-16] */ + + g_coeff[4] = y1y2; + exp_g_coeff[4] = sub (exp_y1y2, 1);; /* 2 */ + + return; +} + + +/*--------------------------------------------------------------------------* + * Function Cor_h_X() * + * ~~~~~~~~~~~~~~~~~~~ * + * Compute correlations of input response h[] with the target vector X[]. * + *--------------------------------------------------------------------------*/ + +void +Cor_h_X (Word16 h[], /* (i) Q12 :Impulse response of filters */ + Word16 X[], /* (i) :Target vector */ + Word16 D[] + /* (o) :Correlations between h[] and D[] */ + /* Normalized to 13 bits */ + ) +{ + Word16 i, j; + Word32 s, max, L_temp; + Word32 y32[L_SUBFR]; + + /* first keep the result on 32 bits and find absolute maximum */ + + max = 0; + + for (i = 0; i < L_SUBFR; i++) { + s = 0; + for (j = i; j < L_SUBFR; j++) + s = L_mac (s, X[j], h[j - i]); + + y32[i] = s; + + s = L_abs (s); + L_temp = L_sub (s, max); + if (L_temp > 0L) { + max = s; + } + } + + /* Find the number of right shifts to do on y32[] */ + /* so that maximum is on 13 bits */ + + j = norm_l (max); + if (sub (j, 16) > 0) { + j = 16; + } + + j = sub (18, j); + + for (i = 0; i < L_SUBFR; i++) { + D[i] = extract_l (L_shr (y32[i], j)); + } + + return; + +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/de_acelp.c asterisk-1.2.1/codecs/g729a_v11/de_acelp.c --- asterisk-1.2.1.ori/codecs/g729a_v11/de_acelp.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/de_acelp.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,73 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-----------------------------------------------------------* + * Function Decod_ACELP() * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * Algebraic codebook decoder. * + *----------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +void +Decod_ACELP (Word16 sign, /* (i) : signs of 4 pulses. */ + Word16 index, /* (i) : Positions of the 4 pulses. */ + Word16 cod[] /* (o) Q13 : algebraic (fixed) codebook excitation */ + ) +{ + Word16 i, j; + Word16 pos[4]; + + + /* Decode the positions */ + + i = index & (Word16) 7; + pos[0] = add (i, shl (i, 2)); /* pos0 =i*5 */ + + index = shr (index, 3); + i = index & (Word16) 7; + i = add (i, shl (i, 2)); /* pos1 =i*5+1 */ + pos[1] = add (i, 1); + + index = shr (index, 3); + i = index & (Word16) 7; + i = add (i, shl (i, 2)); /* pos2 =i*5+1 */ + pos[2] = add (i, 2); + + index = shr (index, 3); + j = index & (Word16) 1; + index = shr (index, 1); + i = index & (Word16) 7; + i = add (i, shl (i, 2)); /* pos3 =i*5+3+j */ + i = add (i, 3); + pos[3] = add (i, j); + + /* decode the signs and build the codeword */ + + for (i = 0; i < L_SUBFR; i++) { + cod[i] = 0; + } + + for (j = 0; j < 4; j++) { + + i = sign & (Word16) 1; + sign = shr (sign, 1); + + if (i != 0) { + cod[pos[j]] = 8191; /* Q13 +1.0 */ + } + else { + cod[pos[j]] = -8192; /* Q13 -1.0 */ + } + } + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/dec_gain.c asterisk-1.2.1/codecs/g729a_v11/dec_gain.c --- asterisk-1.2.1.ori/codecs/g729a_v11/dec_gain.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/dec_gain.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,109 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" + +/*---------------------------------------------------------------------------* + * Function Dec_gain * + * ~~~~~~~~~~~~~~~~~~ * + * Decode the pitch and codebook gains * + * * + *---------------------------------------------------------------------------* + * input arguments: * + * * + * index :Quantization index * + * code[] :Innovative code vector * + * L_subfr :Subframe size * + * bfi :Bad frame indicator * + * * + * output arguments: * + * * + * gain_pit :Quantized pitch gain * + * gain_cod :Quantized codebook gain * + * * + *---------------------------------------------------------------------------*/ +void +Dec_gain (DecState *decoder, + Word16 index, /* (i) :Index of quantization. */ + Word16 code[], /* (i) Q13 :Innovative vector. */ + Word16 L_subfr, /* (i) :Subframe length. */ + Word16 bfi, /* (i) :Bad frame indicator */ + Word16 * gain_pit, /* (o) Q14 :Pitch gain. */ + Word16 * gain_cod /* (o) Q1 :Code gain. */ + ) +{ + Word16 index1, index2, tmp; + Word16 gcode0, exp_gcode0; + Word32 L_gbk12, L_acc, L_accb; + void Gain_predict (Word16 past_qua_en[], Word16 code[], Word16 L_subfr, + Word16 * gcode0, Word16 * exp_gcode0); + void Gain_update (Word16 past_qua_en[], Word32 L_gbk12); + void Gain_update_erasure (Word16 past_qua_en[]); + + /* Gain predictor, Past quantized energies = -14.0 in Q10 */ + + + + /*-------------- Case of erasure. ---------------*/ + + if (bfi != 0) { + *gain_pit = mult (*gain_pit, 29491); /* *0.9 in Q15 */ + if (sub (*gain_pit, 29491) > 0) + *gain_pit = 29491; + *gain_cod = mult (*gain_cod, 32111); /* *0.98 in Q15 */ + + /*----------------------------------------------* + * update table of past quantized energies * + * (frame erasure) * + *----------------------------------------------*/ + Gain_update_erasure (decoder->past_qua_en); + + return; + } + + /*-------------- Decode pitch gain ---------------*/ + + index1 = imap1[shr (index, NCODE2_B)]; + index2 = imap2[index & (NCODE2 - 1)]; + *gain_pit = add (gbk1[index1][0], gbk2[index2][0]); + + /*-------------- Decode codebook gain ---------------*/ + + /*---------------------------------------------------* + *- energy due to innovation -* + *- predicted energy -* + *- predicted codebook gain => gcode0[exp_gcode0] -* + *---------------------------------------------------*/ + + Gain_predict (decoder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0); + + /*-----------------------------------------------------------------* + * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; * + *-----------------------------------------------------------------*/ + + L_acc = L_deposit_l (gbk1[index1][1]); + L_accb = L_deposit_l (gbk2[index2][1]); + L_gbk12 = L_add (L_acc, L_accb); /* Q13 */ + tmp = extract_l (L_shr (L_gbk12, 1)); /* Q12 */ + L_acc = L_mult (tmp, gcode0); /* Q[exp_gcode0+12+1] */ + + L_acc = L_shl (L_acc, add (negate (exp_gcode0), (-12 - 1 + 1 + 16))); + *gain_cod = extract_h (L_acc); /* Q1 */ + + /*----------------------------------------------* + * update table of past quantized energies * + *----------------------------------------------*/ + Gain_update (decoder->past_qua_en, L_gbk12); + + return; + +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/dec_gain.h asterisk-1.2.1/codecs/g729a_v11/dec_gain.h --- asterisk-1.2.1.ori/codecs/g729a_v11/dec_gain.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/dec_gain.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,18 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + + +void Dec_gain (DecState *decoder, + Word16 index, /* (i) : Index of quantization. */ + Word16 code[], /* (i) Q13 : Innovative vector. */ + Word16 L_subfr, /* (i) : Subframe length. */ + Word16 bfi, /* (i) : Bad frame indicator */ + Word16 * gain_pit, /* (o) Q14 : Pitch gain. */ + Word16 * gain_cod /* (o) Q1 : Code gain. */ + ); diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/dec_lag3.c asterisk-1.2.1/codecs/g729a_v11/dec_lag3.c --- asterisk-1.2.1.ori/codecs/g729a_v11/dec_lag3.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/dec_lag3.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,79 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * Function Dec_lag3 * + * ~~~~~~~~ * + * Decoding of fractional pitch lag with 1/3 resolution. * + * See "Enc_lag3.c" for more details about the encoding procedure. * + *------------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +void +Dec_lag3 (Word16 index, /* input : received pitch index */ + Word16 pit_min, /* input : minimum pitch lag */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 i_subfr, /* input : subframe flag */ + Word16 * T0, /* output: integer part of pitch lag */ + Word16 * T0_frac /* output: fractional part of pitch lag */ + ) +{ + Word16 i; + Word16 T0_min, T0_max; + + if (i_subfr == 0) { /* if 1st subframe */ + if (sub (index, 197) < 0) { + /* *T0 = (index+2)/3 + 19 */ + + *T0 = add (mult (add (index, 2), 10923), 19); + + /* *T0_frac = index - *T0*3 + 58 */ + + i = add (add (*T0, *T0), *T0); + *T0_frac = add (sub (index, i), 58); + } + else { + *T0 = sub (index, 112); + *T0_frac = 0; + } + + } + + else { /* second subframe */ + + /* find T0_min and T0_max for 2nd subframe */ + + T0_min = sub (*T0, 5); + if (sub (T0_min, pit_min) < 0) { + T0_min = pit_min; + } + + T0_max = add (T0_min, 9); + if (sub (T0_max, pit_max) > 0) { + T0_max = pit_max; + T0_min = sub (T0_max, 9); + } + + /* i = (index+2)/3 - 1 */ + /* *T0 = i + t0_min; */ + + i = sub (mult (add (index, 2), 10923), 1); + *T0 = add (i, T0_min); + + /* t0_frac = index - 2 - i*3; */ + + i = add (add (i, i), i); + *T0_frac = sub (sub (index, 2), i); + } + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/dec_ld8a.c asterisk-1.2.1/codecs/g729a_v11/dec_ld8a.c --- asterisk-1.2.1.ori/codecs/g729a_v11/dec_ld8a.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/dec_ld8a.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,271 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-----------------------------------------------------------------* + * Functions Init_Decod_ld8a and Decod_ld8a * + *-----------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" +#include "lspdec.h" +#include "util.h" +#include "dec_gain.h" + +/*---------------------------------------------------------------* + * Decoder constant parameters (defined in "ld8a.h") * + *---------------------------------------------------------------* + * L_FRAME : Frame size. * + * L_SUBFR : Sub-frame size. * + * M : LPC order. * + * MP1 : LPC order+1 * + * PIT_MIN : Minimum pitch lag. * + * PIT_MAX : Maximum pitch lag. * + * L_INTERPOL : Length of filter for interpolation * + * PRM_SIZE : Size of vector containing analysis parameters * + *---------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------* + * Function Init_Decod_ld8a * + * ~~~~~~~~~~~~~~~ * + * * + * ->Initialization of variables for the decoder section. * + * * + *-----------------------------------------------------------------*/ + +DecState * +Init_Decod_ld8a (void) +{ + DecState *decoder; + + decoder = (DecState*) malloc (sizeof (DecState)); + + /* Initialize pointers */ + + decoder->exc = decoder->old_exc + PIT_MAX + L_INTERPOL; + + /* Static vectors to zero */ + + Set_zero (decoder->old_exc, PIT_MAX + L_INTERPOL); + Set_zero (decoder->mem_syn, M); + + Copy (lsp_old_init, decoder->lsp_old, M); + + decoder->sharp = SHARPMIN; + decoder->old_T0 = 60; + decoder->gain_code = 0; + decoder->gain_pitch = 0; + + Lsp_decw_reset (decoder); + + decoder->bad_lsf = 0; + Set_zero (decoder->Az_dec, MP1 * 2); + Set_zero (decoder->synth_buf, L_FRAME + M); + Set_zero (decoder->T2, 2); + + Copy (past_qua_en_init, decoder->past_qua_en, 4); + + decoder->seed = 21845; + + return decoder; +} + +/*-----------------------------------------------------------------* + * Function Decod_ld8a * + * ~~~~~~~~~~ * + * ->Main decoder routine. * + * * + *-----------------------------------------------------------------*/ + +void +Decod_ld8a (DecState *decoder, + Word16 parm[], /* (i) : vector of synthesis parameters + parm[0] = bad frame indicator (bfi) */ + Word16 synth[], /* (o) : synthesis speech */ + Word16 A_t[], /* (o) : decoded LP filter in 2 subframes */ + Word16 * T2, /* (o) : decoded pitch lag in 2 subframes */ + Word16 * bad_lsf) +{ + Flag Overflow; + Word16 *Az; /* Pointer on A_t */ + Word16 lsp_new[M]; /* LSPs */ + Word16 code[L_SUBFR]; /* ACELP codevector */ + + /* Scalars */ + + Word16 i, j, i_subfr; + Word16 T0, T0_frac, index; + Word16 bfi; + Word32 L_temp; + + Word16 bad_pitch; /* bad pitch indicator */ + + /* Test bad frame indicator (bfi) */ + + bfi = *parm++; + + /* Decode the LSPs */ + + D_lsp (decoder, parm, lsp_new, add (bfi, *bad_lsf)); + parm += 2; + + /* + Note: "bad_lsf" is introduce in case the standard is used with + channel protection. + */ + + /* Interpolation of LPC for the 2 subframes */ + + Int_qlpc (decoder->lsp_old, lsp_new, A_t); + + /* update the LSFs for the next frame */ + + Copy (lsp_new, decoder->lsp_old, M); + +/*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * + * times * + * - decode the pitch delay * + * - decode algebraic code * + * - decode pitch and codebook gains * + * - find the excitation and compute synthesis speech * + *------------------------------------------------------------------------*/ + + Az = A_t; /* pointer to interpolated LPC parameters */ + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { + + index = *parm++; /* pitch index */ + + if (i_subfr == 0) { + i = *parm++; /* get parity check result */ + bad_pitch = add (bfi, i); + if (bad_pitch == 0) { + Dec_lag3 (index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac); + decoder->old_T0 = T0; + } + else { /* Bad frame, or parity error */ + + T0 = decoder->old_T0; + T0_frac = 0; + decoder->old_T0 = add (decoder->old_T0, 1); + if (sub (decoder->old_T0, PIT_MAX) > 0) { + decoder->old_T0 = PIT_MAX; + } + } + } + else { /* second subframe */ + + if (bfi == 0) { + Dec_lag3 (index, PIT_MIN, PIT_MAX, i_subfr, &T0, &T0_frac); + decoder->old_T0 = T0; + } + else { + T0 = decoder->old_T0; + T0_frac = 0; + decoder->old_T0 = add (decoder->old_T0, 1); + if (sub (decoder->old_T0, PIT_MAX) > 0) { + decoder->old_T0 = PIT_MAX; + } + } + } + *T2++ = T0; + + /*-------------------------------------------------* + * - Find the adaptive codebook vector. * + *-------------------------------------------------*/ + + Pred_lt_3 (&decoder->exc[i_subfr], T0, T0_frac, L_SUBFR); + + /*-------------------------------------------------------* + * - Decode innovative codebook. * + * - Add the fixed-gain pitch contribution to code[]. * + *-------------------------------------------------------*/ + + if (bfi != 0) { /* Bad frame */ + + parm[0] = Random (&decoder->seed) & (Word16) 0x1fff; /* 13 bits random */ + parm[1] = Random (&decoder->seed) & (Word16) 0x000f; /* 4 bits random */ + } + Decod_ACELP (parm[1], parm[0], code); + parm += 2; + + j = shl (decoder->sharp, 1); /* From Q14 to Q15 */ + if (sub (T0, L_SUBFR) < 0) { + for (i = T0; i < L_SUBFR; i++) { + code[i] = add (code[i], mult (code[i - T0], j)); + } + } + + /*-------------------------------------------------* + * - Decode pitch and codebook gains. * + *-------------------------------------------------*/ + + index = *parm++; /* index of energy VQ */ + + Dec_gain (decoder, index, code, L_SUBFR, bfi, &decoder->gain_pitch, &decoder->gain_code); + + /*-------------------------------------------------------------* + * - Update pitch sharpening "sharp" with quantized gain_pitch * + *-------------------------------------------------------------*/ + + decoder->sharp = decoder->gain_pitch; + if (sub (decoder->sharp, SHARPMAX) > 0) { + decoder->sharp = SHARPMAX; + } + if (sub (decoder->sharp, SHARPMIN) < 0) { + decoder->sharp = SHARPMIN; + } + + /*-------------------------------------------------------* + * - Find the total excitation. * + * - Find synthesis speech corresponding to exc[]. * + *-------------------------------------------------------*/ + + for (i = 0; i < L_SUBFR; i++) { + /* exc[i] = gain_pitch*exc[i] + gain_code*code[i]; */ + /* exc[i] in Q0 gain_pitch in Q14 */ + /* code[i] in Q13 gain_codeode in Q1 */ + + L_temp = L_mult (decoder->exc[i + i_subfr], decoder->gain_pitch); + L_temp = L_mac (L_temp, code[i], decoder->gain_code); + L_temp = L_shl (L_temp, 1); + decoder->exc[i + i_subfr] = wround (L_temp); + } + + Overflow = 0; + Syn_filt (Az, &decoder->exc[i_subfr], &synth[i_subfr], L_SUBFR, decoder->mem_syn, 0, &Overflow); + if (Overflow != 0) { + /* In case of overflow in the synthesis */ + /* -> Scale down vector exc[] and redo synthesis */ + + for (i = 0; i < PIT_MAX + L_INTERPOL + L_FRAME; i++) + decoder->old_exc[i] = shr (decoder->old_exc[i], 2); + + Syn_filt (Az, &decoder->exc[i_subfr], &synth[i_subfr], L_SUBFR, decoder->mem_syn, 1, NULL); + } + else + Copy (&synth[i_subfr + L_SUBFR - M], decoder->mem_syn, M); + + Az += MP1; /* interpolated LPC parameters for next subframe */ + } + + /*--------------------------------------------------* + * Update signal for next frame. * + * -> shift to the left by L_FRAME exc[] * + *--------------------------------------------------*/ + + Copy (&decoder->old_exc[L_FRAME], &decoder->old_exc[0], PIT_MAX + L_INTERPOL); + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/dspfunc.c asterisk-1.2.1/codecs/g729a_v11/dspfunc.c --- asterisk-1.2.1.ori/codecs/g729a_v11/dspfunc.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/dspfunc.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,182 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "typedef.h" +#include "basic_op.h" + +#include "ld8a.h" +#include "tab_ld8a.h" + +/*___________________________________________________________________________ + | | + | Function Name : Pow2() | + | | + | L_x = pow(2.0, exponent.fraction) | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function Pow2(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- i = bit10-b15 of fraction, 0 <= i <= 31 | + | 2- a = bit0-b9 of fraction | + | 3- L_x = tabpow[i]<<16 - (tabpow[i] - tabpow[i+1]) * a * 2 | + | 4- L_x = L_x >> (30-exponent) (with rounding) | + |___________________________________________________________________________| +*/ + + +Word32 +Pow2 ( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */ + Word16 exponent, /* (i) Q0 : Integer part. (range: 0<=val<=30) */ + Word16 fraction /* (i) Q15 : Fractional part. (range: 0.0<=val<1.0) */ + ) +{ + Word16 exp, i, a, tmp; + Word32 L_x; + + L_x = L_mult (fraction, 32); /* L_x = fraction<<6 */ + i = extract_h (L_x); /* Extract b10-b15 of fraction */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b0-b9 of fraction */ + a = a & (Word16) 0x7fff; + + L_x = L_deposit_h (tabpow[i]); /* tabpow[i] << 16 */ + tmp = sub (tabpow[i], tabpow[i + 1]); /* tabpow[i] - tabpow[i+1] */ + L_x = L_msu (L_x, tmp, a); /* L_x -= tmp*a*2 */ + + exp = sub (30, exponent); + L_x = L_shr_r (L_x, exp); + + return (L_x); +} + +/*___________________________________________________________________________ + | | + | Function Name : Log2() | + | | + | Compute log2(L_x). | + | L_x is positive. | + | | + | if L_x is negative or zero, result is 0. | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function Log2(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- Normalization of L_x. | + | 2- exponent = 30-exponent | + | 3- i = bit25-b31 of L_x, 32 <= i <= 63 ->because of normalization. | + | 4- a = bit10-b24 | + | 5- i -=32 | + | 6- fraction = tablog[i]<<16 - (tablog[i] - tablog[i+1]) * a * 2 | + |___________________________________________________________________________| +*/ + +void +Log2 (Word32 L_x, /* (i) Q0 : input value */ + Word16 * exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */ + Word16 * fraction /* (o) Q15: Fractional part of Log2. (range: 0<=val<1) */ + ) +{ + Word16 exp, i, a, tmp; + Word32 L_y; + + if (L_x <= (Word32) 0) { + *exponent = 0; + *fraction = 0; + return; + } + + exp = norm_l (L_x); + L_x = L_shl (L_x, exp); /* L_x is normalized */ + + *exponent = sub (30, exp); + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); /* Extract b25-b31 */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b10-b24 of fraction */ + a = a & (Word16) 0x7fff; + + i = sub (i, 32); + + L_y = L_deposit_h (tablog[i]); /* tablog[i] << 16 */ + tmp = sub (tablog[i], tablog[i + 1]); /* tablog[i] - tablog[i+1] */ + L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */ + + *fraction = extract_h (L_y); + + return; +} + +/*___________________________________________________________________________ + | | + | Function Name : Inv_sqrt | + | | + | Compute 1/sqrt(L_x). | + | L_x is positive. | + | | + | if L_x is negative or zero, result is 1 (3fff ffff). | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function 1/sqrt(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- Normalization of L_x. | + | 2- If (30-exponent) is even then shift right once. | + | 3- exponent = (30-exponent)/2 +1 | + | 4- i = bit25-b31 of L_x, 16 <= i <= 63 ->because of normalization. | + | 5- a = bit10-b24 | + | 6- i -=16 | + | 7- L_y = tabsqr[i]<<16 - (tabsqr[i] - tabsqr[i+1]) * a * 2 | + | 8- L_y >>= exponent | + |___________________________________________________________________________| +*/ + + +Word32 +Inv_sqrt ( /* (o) Q30 : output value (range: 0<=val<1) */ + Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ + ) +{ + Word16 exp, i, a, tmp; + Word32 L_y; + + if (L_x <= (Word32) 0) + return ((Word32) 0x3fffffffL); + + exp = norm_l (L_x); + L_x = L_shl (L_x, exp); /* L_x is normalize */ + + exp = sub (30, exp); + if ((exp & 1) == 0) /* If exponent even -> shift right */ + L_x = L_shr (L_x, 1); + + exp = shr (exp, 1); + exp = add (exp, 1); + + L_x = L_shr (L_x, 9); + i = extract_h (L_x); /* Extract b25-b31 */ + L_x = L_shr (L_x, 1); + a = extract_l (L_x); /* Extract b10-b24 */ + a = a & (Word16) 0x7fff; + + i = sub (i, 16); + + L_y = L_deposit_h (tabsqr[i]); /* tabsqr[i] << 16 */ + tmp = sub (tabsqr[i], tabsqr[i + 1]); /* tabsqr[i] - tabsqr[i+1]) */ + L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */ + + L_y = L_shr (L_y, exp); /* denormalization */ + + return (L_y); +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/filter.c asterisk-1.2.1/codecs/g729a_v11/filter.c --- asterisk-1.2.1.ori/codecs/g729a_v11/filter.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/filter.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,128 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------------* + * Function Convolve: * + * ~~~~~~~~~ * + *-------------------------------------------------------------------* + * Perform the convolution between two vectors x[] and h[] and * + * write the result in the vector y[]. * + * All vectors are of length N. * + *-------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +void +Convolve (Word16 x[], /* (i) : input vector */ + Word16 h[], /* (i) Q12 : impulse response */ + Word16 y[], /* (o) : output vector */ + Word16 L /* (i) : vector size */ + ) +{ + Word16 i, n; + Word32 s; + + for (n = 0; n < L; n++) { + s = 0; + for (i = 0; i <= n; i++) + s = L_mac (s, x[i], h[n - i]); + + s = L_shl (s, 3); /* h is in Q12 and saturation */ + y[n] = extract_h (s); + } + + return; +} + +/*-----------------------------------------------------* + * procedure Syn_filt: * + * ~~~~~~~~ * + * Do the synthesis filtering 1/A(z). * + *-----------------------------------------------------*/ + + +void +Syn_filt (Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients (m=10) */ + Word16 x[], /* (i) : input signal */ + Word16 y[], /* (o) : output signal */ + Word16 lg, /* (i) : size of filtering */ + Word16 mem[], /* (i/o) : memory associated with this filtering. */ + Word16 update, /* (i) : 0=no update, 1=update of memory. */ + Flag *Overflow + ) +{ + Flag Over = 0; + Word16 i, j; + Word32 s; + Word16 tmp[100]; /* This is usually done by memory allocation (lg+M) */ + Word16 *yy; + + /* Copy mem[] to yy[] */ + + yy = tmp; + + for (i = 0; i < M; i++) { + *yy++ = mem[i]; + } + + /* Do the filtering. */ + + for (i = 0; i < lg; i++) { + s = L_mult_o (x[i], a[0], &Over); + for (j = 1; j <= M; j++) + s = L_msu_o (s, a[j], yy[-j], &Over); + + s = L_shl_o (s, 3, &Over); + *yy++ = wround_o (s, &Over); + } + + for (i = 0; i < lg; i++) { + y[i] = tmp[i + M]; + } + + /* Update of memory if update==1 */ + + if (update != 0) + for (i = 0; i < M; i++) { + mem[i] = y[lg - M + i]; + } + + if (Overflow != NULL) + *Overflow = Over; + + return; +} + +/*-----------------------------------------------------------------------* + * procedure Residu: * + * ~~~~~~ * + * Compute the LPC residual by filtering the input speech through A(z) * + *-----------------------------------------------------------------------*/ + +void Residu (Word16 a[], /* (i) Q12 : prediction coefficients */ + Word16 x[], /* (i) : speech (values x[-m..-1] are needed */ + Word16 y[], /* (o) : residual signal */ + Word16 lg /* (i) : size of filtering */ + ) +{ + Word16 i, j; + Word32 s; + + for (i = 0; i < lg; i++) { + s = L_mult (x[i], a[0]); + for (j = 1; j <= M; j++) + s = L_mac (s, a[j], x[i - j]); + + s = L_shl (s, 3); + y[i] = wround (s); + } + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/gainpred.c asterisk-1.2.1/codecs/g729a_v11/gainpred.c --- asterisk-1.2.1.ori/codecs/g729a_v11/gainpred.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/gainpred.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,159 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*---------------------------------------------------------------------------* + * Gain_predict() : make gcode0(exp_gcode0) * + * Gain_update() : update table of past quantized energies. * + * Gain_update_erasure() : update table of past quantized energies. * + * (frame erasure) * + * This function is used both Coder and Decoder. * + *---------------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" +#include "oper_32b.h" + +/*---------------------------------------------------------------------------* + * Function Gain_predict * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * MA prediction is performed on the innovation energy (in dB with mean * + * removed). * + *---------------------------------------------------------------------------*/ +void +Gain_predict (Word16 past_qua_en[], /* (i) Q10 :Past quantized energies */ + Word16 code[], /* (i) Q13 :Innovative vector. */ + Word16 L_subfr, /* (i) :Subframe length. */ + Word16 * gcode0, /* (o) Qxx :Predicted codebook gain */ + Word16 * exp_gcode0 /* (o) :Q-Format(gcode0) */ + ) +{ + Word16 i, exp, frac; + Word32 L_tmp; + + /*-------------------------------* + * Energy coming from code * + *-------------------------------*/ + + L_tmp = 0; + for (i = 0; i < L_subfr; i++) + L_tmp = L_mac (L_tmp, code[i], code[i]); + + /*-----------------------------------------------------------------* + * Compute: means_ener - 10log10(ener_code/ L_sufr) * + * Note: mean_ener change from 36 dB to 30 dB because input/2 * + * * + * = 30.0 - 10 log10( ener_code / lcode) + 10log10(2^27) * + * !!ener_code in Q27!! * + * = 30.0 - 3.0103 * log2(ener_code) + 10log10(40) + 10log10(2^27) * + * = 30.0 - 3.0103 * log2(ener_code) + 16.02 + 81.278 * + * = 127.298 - 3.0103 * log2(ener_code) * + *-----------------------------------------------------------------*/ + + Log2 (L_tmp, &exp, &frac); /* Q27->Q0 ^Q0 ^Q15 */ + L_tmp = Mpy_32_16 (exp, frac, -24660); /* Q0 Q15 Q13 -> ^Q14 */ + /* hi:Q0+Q13+1 */ + /* lo:Q15+Q13-15+1 */ + /* -24660[Q13]=-3.0103 */ + L_tmp = L_mac (L_tmp, 32588, 32); /* 32588*32[Q14]=127.298 */ + + /*-----------------------------------------------------------------* + * Compute gcode0. * + * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener * + *-----------------------------------------------------------------*/ + + L_tmp = L_shl (L_tmp, 10); /* From Q14 to Q24 */ + for (i = 0; i < 4; i++) + L_tmp = L_mac (L_tmp, pred[i], past_qua_en[i]); /* Q13*Q10 ->Q24 */ + + *gcode0 = extract_h (L_tmp); /* From Q24 to Q8 */ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) * + * = pow(2, 3.3219*gcode0/20) * + * = pow(2, 0.166*gcode0) * + *-----------------------------------------------------------------*/ + + L_tmp = L_mult (*gcode0, 5439); /* *0.166 in Q15, result in Q24 */ + L_tmp = L_shr (L_tmp, 8); /* From Q24 to Q16 */ + L_Extract (L_tmp, &exp, &frac); /* Extract exponent of gcode0 */ + + *gcode0 = extract_l (Pow2 (14, frac)); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16768 < Pow2() <= 32767 */ + *exp_gcode0 = sub (14, exp); +} + + +/*---------------------------------------------------------------------------* + * Function Gain_update * + * ~~~~~~~~~~~~~~~~~~~~~~ * + * update table of past quantized energies * + *---------------------------------------------------------------------------*/ +void +Gain_update (Word16 past_qua_en[], /* (io) Q10 :Past quantized energies */ + Word32 L_gbk12 /* (i) Q13 : gbk1[indice1][1]+gbk2[indice2][1] */ + ) +{ + Word16 i, tmp; + Word16 exp, frac; + Word32 L_acc; + + for (i = 3; i > 0; i--) { + past_qua_en[i] = past_qua_en[i - 1]; /* Q10 */ + } + /*----------------------------------------------------------------------* + * -- past_qua_en[0] = 20*log10(gbk1[index1][1]+gbk2[index2][1]); -- * + * 2 * 10 log10( gbk1[index1][1]+gbk2[index2][1] ) * + * = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) * + * = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] ) * + * 24660:Q12(6.0205) * + *----------------------------------------------------------------------*/ + + Log2 (L_gbk12, &exp, &frac); /* L_gbk12:Q13 */ + L_acc = L_Comp (sub (exp, 13), frac); /* L_acc:Q16 */ + tmp = extract_h (L_shl (L_acc, 13)); /* tmp:Q13 */ + past_qua_en[0] = mult (tmp, 24660); /* past_qua_en[]:Q10 */ +} + + +/*---------------------------------------------------------------------------* + * Function Gain_update_erasure * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * update table of past quantized energies (frame erasure) * + *---------------------------------------------------------------------------* + * av_pred_en = 0.0; * + * for (i = 0; i < 4; i++) * + * av_pred_en += past_qua_en[i]; * + * av_pred_en = av_pred_en*0.25 - 4.0; * + * if (av_pred_en < -14.0) av_pred_en = -14.0; * + *---------------------------------------------------------------------------*/ +void +Gain_update_erasure (Word16 past_qua_en[] /* (i) Q10 :Past quantized energies */ + ) +{ + Word16 i, av_pred_en; + Word32 L_tmp; + + L_tmp = 0; /* Q10 */ + for (i = 0; i < 4; i++) + L_tmp = L_add (L_tmp, L_deposit_l (past_qua_en[i])); + av_pred_en = extract_l (L_shr (L_tmp, 2)); + av_pred_en = sub (av_pred_en, 4096); /* Q10 */ + + if (sub (av_pred_en, -14336) < 0) { + av_pred_en = -14336; /* 14336:14[Q10] */ + } + + for (i = 3; i > 0; i--) { + past_qua_en[i] = past_qua_en[i - 1]; + } + past_qua_en[0] = av_pred_en; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/ld8a.h asterisk-1.2.1/codecs/g729a_v11/ld8a.h --- asterisk-1.2.1.ori/codecs/g729a_v11/ld8a.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/ld8a.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,471 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include +#include + +typedef struct _CodState CodState; +typedef struct _DecState DecState; + +/*---------------------------------------------------------------* + * LD8A.H * + * ~~~~~~ * + * Function prototypes and constants use for G.729A 8kb/s coder. * + * * + *---------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------* + * Codec constant parameters (coder, decoder, and postfilter) * + *--------------------------------------------------------------------------*/ + +#define L_TOTAL 240 /* Total size of speech buffer. */ +#define L_WINDOW 240 /* Window size in LP analysis. */ +#define L_NEXT 40 /* Lookahead in LP analysis. */ +#define L_FRAME 80 /* Frame size. */ +#define L_SUBFR 40 /* Subframe size. */ +#define M 10 /* Order of LP filter. */ +#define MP1 (M+1) /* Order of LP filter + 1 */ +#define PIT_MIN 20 /* Minimum pitch lag. */ +#define PIT_MAX 143 /* Maximum pitch lag. */ +#define L_INTERPOL (10+1) /* Length of filter for interpolation. */ +#define GAMMA1 24576 /* Bandwitdh factor = 0.75 in Q15 */ + +#define PRM_SIZE 11 /* Size of vector of analysis parameters. */ +#define SERIAL_SIZE (80+2) /* bfi+ number of speech bits */ + +#define SHARPMAX 13017 /* Maximum value of pitch sharpening 0.8 Q14 */ +#define SHARPMIN 3277 /* Minimum value of pitch sharpening 0.2 Q14 */ + + +/*-------------------------------* + * Mathematic functions. * + *-------------------------------*/ + +Word32 Inv_sqrt ( /* (o) Q30 : output value (range: 0<=val<1) */ + Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ + ); + +void Log2 (Word32 L_x, /* (i) Q0 : input value */ + Word16 * exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */ + Word16 * fraction /* (o) Q15: Fractionnal part of Log2. (range: 0<=val<1) */ + ); + +Word32 Pow2 ( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */ + Word16 exponent, /* (i) Q0 : Integer part. (range: 0<=val<=30) */ + Word16 fraction /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */ + ); + +/*-------------------------------* + * Pre and post-process. * + *-------------------------------*/ + +void Init_Post_Process (DecState *decoder); + +void Post_Process (DecState *decoder, + Word16 signal[], /* Input/output signal */ + Word16 lg /* Length of signal */ + ); + +/*-------------------------------* + * LPC analysis and filtering. * + *-------------------------------*/ + +void Autocorr (Word16 x[], /* (i) : Input signal */ + Word16 m, /* (i) : LPC order */ + Word16 r_h[], /* (o) : Autocorrelations (msb) */ + Word16 r_l[] /* (o) : Autocorrelations (lsb) */ + ); + +void Lag_window (Word16 m, /* (i) : LPC order */ + Word16 r_h[], /* (i/o) : Autocorrelations (msb) */ + Word16 r_l[] /* (i/o) : Autocorrelations (lsb) */ + ); + +void Levinson (CodState *coder, + Word16 Rh[], /* (i) : Rh[m+1] Vector of autocorrelations (msb) */ + Word16 Rl[], /* (i) : Rl[m+1] Vector of autocorrelations (lsb) */ + Word16 A[], /* (o) Q12 : A[m] LPC coefficients (m = 10) */ + Word16 rc[] /* (o) Q15 : rc[M] Relection coefficients. */ + ); + +void Az_lsp (Word16 a[], /* (i) Q12 : predictor coefficients */ + Word16 lsp[], /* (o) Q15 : line spectral pairs */ + Word16 old_lsp[] /* (i) : old lsp[] (in case not found 10 roots) */ + ); + +void Lsp_Az (Word16 lsp[], /* (i) Q15 : line spectral frequencies */ + Word16 a[] /* (o) Q12 : predictor coefficients (order = 10) */ + ); + +void Lsf_lsp (Word16 lsf[], /* (i) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 m /* (i) : LPC order */ + ); + +void Lsp_lsf (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 lsf[], /* (o) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 m /* (i) : LPC order */ + ); + +void Int_qlpc (Word16 lsp_old[], /* input : LSP vector of past frame */ + Word16 lsp_new[], /* input : LSP vector of present frame */ + Word16 Az[] /* output: interpolated Az() for the 2 subframes */ + ); + +void Weight_Az (Word16 a[], /* (i) Q12 : a[m+1] LPC coefficients */ + Word16 gamma, /* (i) Q15 : Spectral expansion factor. */ + Word16 m, /* (i) : LPC order. */ + Word16 ap[] /* (o) Q12 : Spectral expanded LPC coefficients */ + ); + +void Residu (Word16 a[], /* (i) Q12 : prediction coefficients */ + Word16 x[], /* (i) : speech (values x[-m..-1] are needed (m=10) */ + Word16 y[], /* (o) : residual signal */ + Word16 lg /* (i) : size of filtering */ + ); + +void Syn_filt (Word16 a[], /* (i) Q12 : a[m+1] prediction coefficients (m=10) */ + Word16 x[], /* (i) : input signal */ + Word16 y[], /* (o) : output signal */ + Word16 lg, /* (i) : size of filtering */ + Word16 mem[], /* (i/o) : memory associated with this filtering. */ + Word16 update, /* (i) : 0=no update, 1=update of memory. */ + Flag *Overflow + ); + +void Convolve (Word16 x[], /* (i) : input vector */ + Word16 h[], /* (i) Q12 : impulse response */ + Word16 y[], /* (o) : output vector */ + Word16 L /* (i) : vector size */ + ); + +/*--------------------------------------------------------------------------* + * LTP constant parameters * + *--------------------------------------------------------------------------*/ + +#define UP_SAMP 3 +#define L_INTER10 10 +#define FIR_SIZE_SYN (UP_SAMP*L_INTER10+1) + +/*-----------------------* + * Pitch functions. * + *-----------------------*/ + +Word16 Pitch_ol_fast ( /* output: open loop pitch lag */ + Word16 signal[], /* input : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 L_frame /* input : length of frame to compute pitch */ + ); + +Word16 Pitch_fr3_fast ( /* (o) : pitch period. */ + Word16 exc[], /* (i) : excitation buffer */ + Word16 xn[], /* (i) : target vector */ + Word16 h[], /* (i) Q12 : impulse response of filters. */ + Word16 L_subfr, /* (i) : Length of subframe */ + Word16 t0_min, /* (i) : minimum value in the searched range. */ + Word16 t0_max, /* (i) : maximum value in the searched range. */ + Word16 i_subfr, /* (i) : indicator for first subframe. */ + Word16 * pit_frac /* (o) : chosen fraction. */ + ); + +Word16 G_pitch ( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */ + Word16 xn[], /* (i) : Pitch target. */ + Word16 y1[], /* (i) : Filtered adaptive codebook. */ + Word16 g_coeff[], /* (i) : Correlations need for gain quantization. */ + Word16 L_subfr /* (i) : Length of subframe. */ + ); + +Word16 Enc_lag3 ( /* output: Return index of encoding */ + Word16 T0, /* input : Pitch delay */ + Word16 T0_frac, /* input : Fractional pitch delay */ + Word16 * T0_min, /* in/out: Minimum search delay */ + Word16 * T0_max, /* in/out: Maximum search delay */ + Word16 pit_min, /* input : Minimum pitch delay */ + Word16 pit_max, /* input : Maximum pitch delay */ + Word16 pit_flag /* input : Flag for 1st subframe */ + ); + +void Dec_lag3 ( /* output: return integer pitch lag */ + Word16 index, /* input : received pitch index */ + Word16 pit_min, /* input : minimum pitch lag */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 i_subfr, /* input : subframe flag */ + Word16 * T0, /* output: integer part of pitch lag */ + Word16 * T0_frac /* output: fractional part of pitch lag */ + ); + +Word16 Interpol_3 ( /* (o) : interpolated value */ + Word16 * x, /* (i) : input vector */ + Word16 frac /* (i) : fraction */ + ); + +void Pred_lt_3 (Word16 exc[], /* in/out: excitation buffer */ + Word16 T0, /* input : integer pitch lag */ + Word16 frac, /* input : fraction of lag */ + Word16 L_subfr /* input : subframe size */ + ); + +Word16 Parity_Pitch ( /* output: parity bit (XOR of 6 MSB bits) */ + Word16 pitch_index /* input : index for which parity to compute */ + ); + +Word16 Check_Parity_Pitch ( /* output: 0 = no error, 1= error */ + Word16 pitch_index, /* input : index of parameter */ + Word16 parity /* input : parity bit */ + ); + +void Cor_h_X (Word16 h[], /* (i) Q12 :Impulse response of filters */ + Word16 X[], /* (i) :Target vector */ + Word16 D[] + /* (o) :Correlations between h[] and D[] */ + /* Normalized to 13 bits */ + ); + +/*-----------------------* + * Innovative codebook. * + *-----------------------*/ + +#define DIM_RR 616 /* size of correlation matrix */ +#define NB_POS 8 /* Number of positions for each pulse */ +#define STEP 5 /* Step betweem position of the same pulse. */ +#define MSIZE 64 /* Size of vectors for cross-correlation between 2 pulses */ + +/* The following constants are Q15 fractions. + These fractions is used to keep maximum precision on "alp" sum */ + +#define _1_2 (Word16)(16384) +#define _1_4 (Word16)( 8192) +#define _1_8 (Word16)( 4096) +#define _1_16 (Word16)( 2048) + +Word16 ACELP_Code_A ( /* (o) :index of pulses positions */ + Word16 x[], /* (i) :Target vector */ + Word16 h[], /* (i) Q12 :Inpulse response of filters */ + Word16 T0, /* (i) :Pitch lag */ + Word16 pitch_sharp, /* (i) Q14 :Last quantized pitch gain */ + Word16 code[], /* (o) Q13 :Innovative codebook */ + Word16 y[], /* (o) Q12 :Filtered innovative codebook */ + Word16 * sign /* (o) :Signs of 4 pulses */ + ); + +void Decod_ACELP (Word16 sign, /* (i) : signs of 4 pulses. */ + Word16 index, /* (i) : Positions of the 4 pulses. */ + Word16 cod[] /* (o) Q13 : algebraic (fixed) codebook excitation */ + ); + +/*--------------------------------------------------------------------------* + * LSP constant parameters * + *--------------------------------------------------------------------------*/ + +#define NC 5 /* NC = M/2 */ +#define MA_NP 4 /* MA prediction order for LSP */ +#define MODE 2 /* number of modes for MA prediction */ +#define NC0_B 7 /* number of first stage bits */ +#define NC1_B 5 /* number of second stage bits */ +#define NC0 (1< mantissa in Q31 plus exponent | + | A[i] Q27 +- 15.999.. | + | | + | The additions are performed in 32 bit. For the summation used | + | to calculate the K[i], we multiply numbers in Q31 by numbers | + | in Q27, with the result of the multiplications in Q27, | + | resulting in a dynamic of +- 16. This is sufficient to avoid | + | overflow, since the final result of the summation is | + | necessarily < 1.0 as both the K[i] and Alpha are | + | theoretically < 1.0. | + |___________________________________________________________________________| +*/ + + +/* Last A(z) for case of unstable filter */ + +void +Levinson (CodState *coder, + Word16 Rh[], /* (i) : Rh[M+1] Vector of autocorrelations (msb) */ + Word16 Rl[], /* (i) : Rl[M+1] Vector of autocorrelations (lsb) */ + Word16 A[], /* (o) Q12 : A[M] LPC coefficients (m = 10) */ + Word16 rc[] /* (o) Q15 : rc[M] Reflection coefficients. */ + ) +{ + Word16 i, j; + Word16 hi, lo; + Word16 Kh, Kl; /* reflection coefficient; hi and lo */ + Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */ + Word16 Ah[M + 1], Al[M + 1]; /* LPC coef. in double prec. */ + Word16 Anh[M + 1], Anl[M + 1]; /* LPC coef.for next iteration in double prec. */ + Word32 t0, t1, t2; /* temporary variable */ + + +/* K = A[1] = -R[1] / R[0] */ + + t1 = L_Comp (Rh[1], Rl[1]); /* R[1] in Q31 */ + t2 = L_abs (t1); /* abs R[1] */ + t0 = Div_32 (t2, Rh[0], Rl[0]); /* R[1]/R[0] in Q31 */ + if (t1 > 0) + t0 = L_negate (t0); /* -R[1]/R[0] */ + L_Extract (t0, &Kh, &Kl); /* K in DPF */ + rc[0] = Kh; + t0 = L_shr (t0, 4); /* A[1] in Q27 */ + L_Extract (t0, &Ah[1], &Al[1]); /* A[1] in DPF */ + +/* Alpha = R[0] * (1-K**2) */ + + t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K in Q31 */ + t0 = L_abs (t0); /* Some case <0 !! */ + t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */ + L_Extract (t0, &hi, &lo); /* DPF format */ + t0 = Mpy_32 (Rh[0], Rl[0], hi, lo); /* Alpha in Q31 */ + +/* Normalize Alpha */ + + alp_exp = norm_l (t0); + t0 = L_shl (t0, alp_exp); + L_Extract (t0, &alp_h, &alp_l); /* DPF format */ + +/*--------------------------------------* + * ITERATIONS I=2 to M * + *--------------------------------------*/ + + for (i = 2; i <= M; i++) { + + /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */ + + t0 = 0; + for (j = 1; j < i; j++) + t0 = L_add (t0, Mpy_32 (Rh[j], Rl[j], Ah[i - j], Al[i - j])); + + t0 = L_shl (t0, 4); /* result in Q27 -> convert to Q31 */ + /* No overflow possible */ + t1 = L_Comp (Rh[i], Rl[i]); + t0 = L_add (t0, t1); /* add R[i] in Q31 */ + + /* K = -t0 / Alpha */ + + t1 = L_abs (t0); + t2 = Div_32 (t1, alp_h, alp_l); /* abs(t0)/Alpha */ + if (t0 > 0) + t2 = L_negate (t2); /* K =-t0/Alpha */ + t2 = L_shl (t2, alp_exp); /* denormalize; compare to Alpha */ + L_Extract (t2, &Kh, &Kl); /* K in DPF */ + rc[i - 1] = Kh; + + /* Test for unstable filter. If unstable keep old A(z) */ + + if (sub (abs_s (Kh), 32750) > 0) { + for (j = 0; j <= M; j++) { + A[j] = coder->old_A[j]; + } + rc[0] = coder->old_rc[0]; /* only two rc coefficients are needed */ + rc[1] = coder->old_rc[1]; + return; + } + + /*------------------------------------------* + * Compute new LPC coeff. -> An[i] * + * An[j]= A[j] + K*A[i-j] , j=1 to i-1 * + * An[i]= K * + *------------------------------------------*/ + + + for (j = 1; j < i; j++) { + t0 = Mpy_32 (Kh, Kl, Ah[i - j], Al[i - j]); + t0 = L_add (t0, L_Comp (Ah[j], Al[j])); + L_Extract (t0, &Anh[j], &Anl[j]); + } + t2 = L_shr (t2, 4); /* t2 = K in Q31 ->convert to Q27 */ + L_Extract (t2, &Anh[i], &Anl[i]); /* An[i] in Q27 */ + + /* Alpha = Alpha * (1-K**2) */ + + t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K in Q31 */ + t0 = L_abs (t0); /* Some case <0 !! */ + t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */ + L_Extract (t0, &hi, &lo); /* DPF format */ + t0 = Mpy_32 (alp_h, alp_l, hi, lo); /* Alpha in Q31 */ + + /* Normalize Alpha */ + + j = norm_l (t0); + t0 = L_shl (t0, j); + L_Extract (t0, &alp_h, &alp_l); /* DPF format */ + alp_exp = add (alp_exp, j); /* Add normalization to alp_exp */ + + /* A[j] = An[j] */ + + for (j = 1; j <= i; j++) { + Ah[j] = Anh[j]; + Al[j] = Anl[j]; + } + } + + /* Truncate A[i] in Q27 to Q12 with rounding */ + + A[0] = 4096; + for (i = 1; i <= M; i++) { + t0 = L_Comp (Ah[i], Al[i]); + coder->old_A[i] = A[i] = wround (L_shl (t0, 1)); + } + coder->old_rc[0] = rc[0]; + coder->old_rc[1] = rc[1]; + + return; +} + + + +/*-------------------------------------------------------------* + * procedure Az_lsp: * + * ~~~~~~ * + * Compute the LSPs from the LPC coefficients (order=10) * + *-------------------------------------------------------------*/ + +Word16 Chebps_11 (Word16 x, Word16 f[], Word16 n); +Word16 Chebps_10 (Word16 x, Word16 f[], Word16 n); + +void +Az_lsp (Word16 a[], /* (i) Q12 : predictor coefficients */ + Word16 lsp[], /* (o) Q15 : line spectral pairs */ + Word16 old_lsp[] /* (i) : old lsp[] (in case not found 10 roots) */ + ) +{ + Flag Overflow; + Word16 i, j, nf, ip; + Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint; + Word16 x, y, sign, exp; + Word16 *coef; + Word16 f1[M / 2 + 1], f2[M / 2 + 1]; + Word32 t0, L_temp; + Flag ovf_coef; + Word16 (*pChebps) (Word16 x, Word16 f[], Word16 n); + +/*-------------------------------------------------------------* + * find the sum and diff. pol. F1(z) and F2(z) * + * F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1) * + * * + * f1[0] = 1.0; * + * f2[0] = 1.0; * + * * + * for (i = 0; i< NC; i++) * + * { * + * f1[i+1] = a[i+1] + a[M-i] - f1[i] ; * + * f2[i+1] = a[i+1] - a[M-i] + f2[i] ; * + * } * + *-------------------------------------------------------------*/ + + ovf_coef = 0; + pChebps = Chebps_11; + + f1[0] = 2048; /* f1[0] = 1.0 is in Q11 */ + f2[0] = 2048; /* f2[0] = 1.0 is in Q11 */ + + for (i = 0; i < NC; i++) { + Overflow = 0; + t0 = L_mult_o (a[i + 1], 16384, &Overflow); /* x = (a[i+1] + a[M-i]) >> 1 */ + t0 = L_mac_o (t0, a[M - i], 16384, &Overflow); /* -> From Q12 to Q11 */ + x = extract_h (t0); + if (Overflow) { + ovf_coef = 1; + } + + Overflow = 0; + f1[i + 1] = sub_o (x, f1[i], &Overflow); /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */ + if (Overflow) { + ovf_coef = 1; + } + + Overflow = 0; + t0 = L_mult_o (a[i + 1], 16384, &Overflow); /* x = (a[i+1] - a[M-i]) >> 1 */ + t0 = L_msu_o (t0, a[M - i], 16384, &Overflow); /* -> From Q12 to Q11 */ + x = extract_h (t0); + if (Overflow) { + ovf_coef = 1; + } + + Overflow = 0; + f2[i + 1] = add_o (x, f2[i], &Overflow); /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */ + if (Overflow) { + ovf_coef = 1; + } + } + + if (ovf_coef) { + /*printf("===== OVF ovf_coef =====\n"); */ + + pChebps = Chebps_10; + + f1[0] = 1024; /* f1[0] = 1.0 is in Q10 */ + f2[0] = 1024; /* f2[0] = 1.0 is in Q10 */ + + for (i = 0; i < NC; i++) { + t0 = L_mult (a[i + 1], 8192); /* x = (a[i+1] + a[M-i]) >> 1 */ + t0 = L_mac (t0, a[M - i], 8192); /* -> From Q11 to Q10 */ + x = extract_h (t0); + f1[i + 1] = sub (x, f1[i]); /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */ + + t0 = L_mult (a[i + 1], 8192); /* x = (a[i+1] - a[M-i]) >> 1 */ + t0 = L_msu (t0, a[M - i], 8192); /* -> From Q11 to Q10 */ + x = extract_h (t0); + f2[i + 1] = add (x, f2[i]); /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */ + } + } + +/*-------------------------------------------------------------* + * find the LSPs using the Chebichev pol. evaluation * + *-------------------------------------------------------------*/ + + nf = 0; /* number of found frequencies */ + ip = 0; /* indicator for f1 or f2 */ + + coef = f1; + + xlow = grid[0]; + ylow = (*pChebps) (xlow, coef, NC); + + j = 0; + while ((nf < M) && (j < GRID_POINTS)) { + j = add (j, 1); + xhigh = xlow; + yhigh = ylow; + xlow = grid[j]; + ylow = (*pChebps) (xlow, coef, NC); + + L_temp = L_mult (ylow, yhigh); + if (L_temp <= (Word32) 0) { + + /* divide 2 times the interval */ + + for (i = 0; i < 2; i++) { + xmid = add (shr (xlow, 1), shr (xhigh, 1)); /* xmid = (xlow + xhigh)/2 */ + + ymid = (*pChebps) (xmid, coef, NC); + + L_temp = L_mult (ylow, ymid); + if (L_temp <= (Word32) 0) { + yhigh = ymid; + xhigh = xmid; + } + else { + ylow = ymid; + xlow = xmid; + } + } + + /*-------------------------------------------------------------* + * Linear interpolation * + * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow); * + *-------------------------------------------------------------*/ + + x = sub (xhigh, xlow); + y = sub (yhigh, ylow); + + if (y == 0) { + xint = xlow; + } + else { + sign = y; + y = abs_s (y); + exp = norm_s (y); + y = shl (y, exp); + y = div_s ((Word16) 16383, y); + t0 = L_mult (x, y); + t0 = L_shr (t0, sub (20, exp)); + y = extract_l (t0); /* y= (xhigh-xlow)/(yhigh-ylow) in Q11 */ + + if (sign < 0) + y = negate (y); + + t0 = L_mult (ylow, y); /* result in Q26 */ + t0 = L_shr (t0, 11); /* result in Q15 */ + xint = sub (xlow, extract_l (t0)); /* xint = xlow - ylow*y */ + } + + lsp[nf] = xint; + xlow = xint; + nf = add (nf, 1); + + if (ip == 0) { + ip = 1; + coef = f2; + } + else { + ip = 0; + coef = f1; + } + ylow = (*pChebps) (xlow, coef, NC); + + } + } + + /* Check if M roots found */ + + if (sub (nf, M) < 0) { + for (i = 0; i < M; i++) { + lsp[i] = old_lsp[i]; + } + + /* printf("\n !!Not 10 roots found in Az_lsp()!!!\n"); */ + } + + return; +} + +/*--------------------------------------------------------------* + * function Chebps_11, Chebps_10: * + * ~~~~~~~~~~~~~~~~~~~~ * + * Evaluates the Chebichev polynomial series * + *--------------------------------------------------------------* + * * + * The polynomial order is * + * n = M/2 (M is the prediction order) * + * The polynomial is given by * + * C(x) = T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 * + * Arguments: * + * x: input value of evaluation; x = cos(frequency) in Q15 * + * f[]: coefficients of the pol. * + * in Q11(Chebps_11), in Q10(Chebps_10) * + * n: order of the pol. * + * * + * The value of C(x) is returned. (Saturated to +-1.99 in Q14) * + * * + *--------------------------------------------------------------*/ +Word16 +Chebps_11 (Word16 x, Word16 f[], Word16 n) +{ + Word16 i, cheb; + Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l; + Word32 t0; + + /* Note: All computation are done in Q24. */ + + b2_h = 256; /* b2 = 1.0 in Q24 DPF */ + b2_l = 0; + + t0 = L_mult (x, 512); /* 2*x in Q24 */ + t0 = L_mac (t0, f[1], 4096); /* + f[1] in Q24 */ + L_Extract (t0, &b1_h, &b1_l); /* b1 = 2*x + f[1] */ + + for (i = 2; i < n; i++) { + t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = 2.0*x*b1 */ + t0 = L_shl (t0, 1); + t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = 2.0*x*b1 - b2 */ + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 4096); /* t0 = 2.0*x*b1 - b2 + f[i]; */ + + L_Extract (t0, &b0_h, &b0_l); /* b0 = 2.0*x*b1 - b2 + f[i]; */ + + b2_l = b1_l; /* b2 = b1; */ + b2_h = b1_h; + b1_l = b0_l; /* b1 = b0; */ + b1_h = b0_h; + } + + t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = x*b1; */ + t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = x*b1 - b2 */ + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 2048); /* t0 = x*b1 - b2 + f[i]/2 */ + + t0 = L_shl (t0, 6); /* Q24 to Q30 with saturation */ + cheb = extract_h (t0); /* Result in Q14 */ + + + return (cheb); +} + + +Word16 +Chebps_10 (Word16 x, Word16 f[], Word16 n) +{ + Word16 i, cheb; + Word16 b0_h, b0_l, b1_h, b1_l, b2_h, b2_l; + Word32 t0; + + /* Note: All computation are done in Q23. */ + + b2_h = 128; /* b2 = 1.0 in Q23 DPF */ + b2_l = 0; + + t0 = L_mult (x, 256); /* 2*x in Q23 */ + t0 = L_mac (t0, f[1], 4096); /* + f[1] in Q23 */ + L_Extract (t0, &b1_h, &b1_l); /* b1 = 2*x + f[1] */ + + for (i = 2; i < n; i++) { + t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = 2.0*x*b1 */ + t0 = L_shl (t0, 1); + t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = 2.0*x*b1 - b2 */ + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 4096); /* t0 = 2.0*x*b1 - b2 + f[i]; */ + + L_Extract (t0, &b0_h, &b0_l); /* b0 = 2.0*x*b1 - b2 + f[i]; */ + + b2_l = b1_l; /* b2 = b1; */ + b2_h = b1_h; + b1_l = b0_l; /* b1 = b0; */ + b1_h = b0_h; + } + + t0 = Mpy_32_16 (b1_h, b1_l, x); /* t0 = x*b1; */ + t0 = L_mac (t0, b2_h, (Word16) - 32768L); /* t0 = x*b1 - b2 */ + t0 = L_msu (t0, b2_l, 1); + t0 = L_mac (t0, f[i], 2048); /* t0 = x*b1 - b2 + f[i]/2 */ + + t0 = L_shl (t0, 7); /* Q23 to Q30 with saturation */ + cheb = extract_h (t0); /* Result in Q14 */ + + + return (cheb); +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/lpcfunc.c asterisk-1.2.1/codecs/g729a_v11/lpcfunc.c --- asterisk-1.2.1.ori/codecs/g729a_v11/lpcfunc.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/lpcfunc.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,300 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------* + * Procedure Lsp_Az: * + * ~~~~~~ * + * Compute the LPC coefficients from lsp (order=10) * + *-------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" + +#include "ld8a.h" +#include "tab_ld8a.h" + +/* local function */ + +void Get_lsp_pol (Word16 * lsp, Word32 * f); + +void +Lsp_Az (Word16 lsp[], /* (i) Q15 : line spectral frequencies */ + Word16 a[] /* (o) Q12 : predictor coefficients (order = 10) */ + ) +{ + Word16 i, j; + Word32 f1[6], f2[6]; + Word32 t0; + + Get_lsp_pol (&lsp[0], f1); + Get_lsp_pol (&lsp[1], f2); + + for (i = 5; i > 0; i--) { + f1[i] = L_add (f1[i], f1[i - 1]); /* f1[i] += f1[i-1]; */ + f2[i] = L_sub (f2[i], f2[i - 1]); /* f2[i] -= f2[i-1]; */ + } + + a[0] = 4096; + for (i = 1, j = 10; i <= 5; i++, j--) { + t0 = L_add (f1[i], f2[i]); /* f1[i] + f2[i] */ + a[i] = extract_l (L_shr_r (t0, 13)); /* from Q24 to Q12 and * 0.5 */ + + t0 = L_sub (f1[i], f2[i]); /* f1[i] - f2[i] */ + a[j] = extract_l (L_shr_r (t0, 13)); /* from Q24 to Q12 and * 0.5 */ + + } + + return; +} + +/*-----------------------------------------------------------* + * procedure Get_lsp_pol: * + * ~~~~~~~~~~~ * + * Find the polynomial F1(z) or F2(z) from the LSPs * + *-----------------------------------------------------------* + * * + * Parameters: * + * lsp[] : line spectral freq. (cosine domain) in Q15 * + * f[] : the coefficients of F1 or F2 in Q24 * + *-----------------------------------------------------------*/ + +void +Get_lsp_pol (Word16 * lsp, Word32 * f) +{ + Word16 i, j, hi, lo; + Word32 t0; + + /* All computation in Q24 */ + + *f = L_mult (4096, 2048); /* f[0] = 1.0; in Q24 */ + f++; + *f = L_msu ((Word32) 0, *lsp, 512); /* f[1] = -2.0 * lsp[0]; in Q24 */ + + f++; + lsp += 2; /* Advance lsp pointer */ + + for (i = 2; i <= 5; i++) { + *f = f[-2]; + + for (j = 1; j < i; j++, f--) { + L_Extract (f[-1], &hi, &lo); + t0 = Mpy_32_16 (hi, lo, *lsp); /* t0 = f[-1] * lsp */ + t0 = L_shl (t0, 1); + *f = L_add (*f, f[-2]); /* *f += f[-2] */ + *f = L_sub (*f, t0); /* *f -= t0 */ + } + *f = L_msu (*f, *lsp, 512); /* *f -= lsp<<9 */ + f += i; /* Advance f pointer */ + lsp += 2; /* Advance lsp pointer */ + } + + return; +} + +/*___________________________________________________________________________ + | | + | Functions : Lsp_lsf and Lsf_lsp | + | | + | Lsp_lsf Transformation lsp to lsf | + | Lsf_lsp Transformation lsf to lsp | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The transformation from lsp[i] to lsf[i] and lsf[i] to lsp[i] are | + | approximated by a look-up table and interpolation. | + |___________________________________________________________________________| +*/ + + +void +Lsf_lsp (Word16 lsf[], /* (i) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 m /* (i) : LPC order */ + ) +{ + Word16 i, ind, offset; + Word32 L_tmp; + + for (i = 0; i < m; i++) { + ind = shr (lsf[i], 8); /* ind = b8-b15 of lsf[i] */ + offset = lsf[i] & (Word16) 0x00ff; /* offset = b0-b7 of lsf[i] */ + + /* lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256 */ + + L_tmp = L_mult (sub (table[ind + 1], table[ind]), offset); + lsp[i] = add (table[ind], extract_l (L_shr (L_tmp, 9))); + } + return; +} + + +void +Lsp_lsf (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 lsf[], /* (o) Q15 : lsf[m] normalized (range: 0.0<=val<=0.5) */ + Word16 m /* (i) : LPC order */ + ) +{ + Word16 i, ind, tmp; + Word32 L_tmp; + + ind = 63; /* begin at end of table -1 */ + + for (i = m - (Word16) 1; i >= 0; i--) { + /* find value in table that is just greater than lsp[i] */ + while (sub (table[ind], lsp[i]) < 0) { + ind = sub (ind, 1); + } + + /* acos(lsp[i])= ind*256 + ( ( lsp[i]-table[ind] ) * slope[ind] )/4096 */ + + L_tmp = L_mult (sub (lsp[i], table[ind]), slope[ind]); + tmp = wround (L_shl (L_tmp, 3)); /*(lsp[i]-table[ind])*slope[ind])>>12 */ + lsf[i] = add (tmp, shl (ind, 8)); + } + return; +} + +/*___________________________________________________________________________ + | | + | Functions : Lsp_lsf and Lsf_lsp | + | | + | Lsp_lsf Transformation lsp to lsf | + | Lsf_lsp Transformation lsf to lsp | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The transformation from lsp[i] to lsf[i] and lsf[i] to lsp[i] are | + | approximated by a look-up table and interpolation. | + |___________________________________________________________________________| +*/ + +void +Lsf_lsp2 (Word16 lsf[], /* (i) Q13 : lsf[m] (range: 0.0<=val 0) { + ind = 63; /* 0 <= ind <= 63 */ + } + + /* lsp[i] = table2[ind]+ (slope_cos[ind]*offset >> 12) */ + + L_tmp = L_mult (slope_cos[ind], offset); /* L_tmp in Q28 */ + lsp[i] = add (table2[ind], extract_l (L_shr (L_tmp, 13))); + + } + return; +} + + + +void +Lsp_lsf2 (Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */ + Word16 lsf[], /* (o) Q13 : lsf[m] (range: 0.0<=val= 0; i--) { + /* find value in table2 that is just greater than lsp[i] */ + while (sub (table2[ind], lsp[i]) < 0) { + ind = sub (ind, 1); + if (ind <= 0) + break; + } + + offset = sub (lsp[i], table2[ind]); + + /* acos(lsp[i])= ind*512 + (slope_acos[ind]*offset >> 11) */ + + L_tmp = L_mult (slope_acos[ind], offset); /* L_tmp in Q28 */ + freq = add (shl (ind, 9), extract_l (L_shr (L_tmp, 12))); + lsf[i] = mult (freq, 25736); /* 25736: 2.0*PI in Q12 */ + + } + return; +} + +/*-------------------------------------------------------------* + * procedure Weight_Az * + * ~~~~~~~~~ * + * Weighting of LPC coefficients. * + * ap[i] = a[i] * (gamma ** i) * + * * + *-------------------------------------------------------------*/ + + +void +Weight_Az (Word16 a[], /* (i) Q12 : a[m+1] LPC coefficients */ + Word16 gamma, /* (i) Q15 : Spectral expansion factor. */ + Word16 m, /* (i) : LPC order. */ + Word16 ap[] /* (o) Q12 : Spectral expanded LPC coefficients */ + ) +{ + Word16 i, fac; + + ap[0] = a[0]; + fac = gamma; + for (i = 1; i < m; i++) { + ap[i] = wround (L_mult (a[i], fac)); + fac = wround (L_mult (fac, gamma)); + } + ap[m] = wround (L_mult (a[m], fac)); + + return; +} + +/*----------------------------------------------------------------------* + * Function Int_qlpc() * + * ~~~~~~~~~~~~~~~~~~~ * + * Interpolation of the LPC parameters. * + *----------------------------------------------------------------------*/ + +/* Interpolation of the quantized LSP's */ + +void +Int_qlpc (Word16 lsp_old[], /* input : LSP vector of past frame */ + Word16 lsp_new[], /* input : LSP vector of present frame */ + Word16 Az[] /* output: interpolated Az() for the 2 subframes */ + ) +{ + Word16 i; + Word16 lsp[M]; + + /* lsp[i] = lsp_new[i] * 0.5 + lsp_old[i] * 0.5 */ + + for (i = 0; i < M; i++) { + lsp[i] = add (shr (lsp_new[i], 1), shr (lsp_old[i], 1)); + } + + Lsp_Az (lsp, Az); /* Subframe 1 */ + + Lsp_Az (lsp_new, &Az[MP1]); /* Subframe 2 */ + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/lpcfunc.h asterisk-1.2.1/codecs/g729a_v11/lpcfunc.h --- asterisk-1.2.1.ori/codecs/g729a_v11/lpcfunc.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/lpcfunc.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,18 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +void Lsf_lsp2 (Word16 lsf[], /* (i) Q13 : lsf[m] (range: 0.0<=valfreq_prev[i][0], M); + + decoder->prev_ma = 0; + + Copy (freq_prev_reset, decoder->prev_lsp, M); +} + + + +/*---------------------------------------------------------------------------- + * Lsp_iqua_cs - LSP main quantization routine + *---------------------------------------------------------------------------- + */ +void +Lsp_iqua_cs (DecState *decoder, + Word16 prm[], /* (i) : indexes of the selected LSP */ + Word16 lsp_q[], /* (o) Q13 : Quantized LSP parameters */ + Word16 erase /* (i) : frame erase information */ + ) +{ + Word16 mode_index; + Word16 code0; + Word16 code1; + Word16 code2; + Word16 buf[M]; /* Q13 */ + + if (erase == 0) { /* Not frame erasure */ + mode_index = shr (prm[0], NC0_B) & (Word16) 1; + code0 = prm[0] & (Word16) (NC0 - 1); + code1 = shr (prm[1], NC1_B) & (Word16) (NC1 - 1); + code2 = prm[1] & (Word16) (NC1 - 1); + + /* compose quantized LSP (lsp_q) from indexes */ + + Lsp_get_quant (lspcb1, lspcb2, code0, code1, code2, + fg[mode_index], decoder->freq_prev, lsp_q, fg_sum[mode_index]); + + /* save parameters to use in case of the frame erased situation */ + + Copy (lsp_q, decoder->prev_lsp, M); + decoder->prev_ma = mode_index; + } + else { /* Frame erased */ + /* use revious LSP */ + + Copy (decoder->prev_lsp, lsp_q, M); + + /* update freq_prev */ + + Lsp_prev_extract (decoder->prev_lsp, buf, + fg[decoder->prev_ma], decoder->freq_prev, fg_sum_inv[decoder->prev_ma]); + Lsp_prev_update (buf, decoder->freq_prev); + } + + return; +} + + + +/*-------------------------------------------------------------------* + * Function D_lsp: * + * ~~~~~~ * + *-------------------------------------------------------------------*/ + +void +D_lsp (DecState *decoder, + Word16 prm[], /* (i) : indexes of the selected LSP */ + Word16 lsp_q[], /* (o) Q15 : Quantized LSP parameters */ + Word16 erase /* (i) : frame erase information */ + ) +{ + Word16 lsf_q[M]; /* domain 0.0<= lsf_q +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "util.h" +#include "lspgetq.h" + + +void +Lsp_get_quant (Word16 lspcb1[][M], /* (i) Q13 : first stage LSP codebook */ + Word16 lspcb2[][M], /* (i) Q13 : Second stage LSP codebook */ + Word16 code0, /* (i) : selected code of first stage */ + Word16 code1, /* (i) : selected code of second stage */ + Word16 code2, /* (i) : selected code of second stage */ + Word16 fg[][M], /* (i) Q15 : MA prediction coef. */ + Word16 freq_prev[][M], /* (i) Q13 : previous LSP vector */ + Word16 lspq[], /* (o) Q13 : quantized LSP parameters */ + Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */ + ) +{ + Word16 j; + Word16 buf[M]; /* Q13 */ + + + for (j = 0; j < NC; j++) + buf[j] = add (lspcb1[code0][j], lspcb2[code1][j]); + + for (j = NC; j < M; j++) + buf[j] = add (lspcb1[code0][j], lspcb2[code2][j]); + + Lsp_expand_1_2 (buf, GAP1); + Lsp_expand_1_2 (buf, GAP2); + + Lsp_prev_compose (buf, lspq, fg, freq_prev, fg_sum); + + Lsp_prev_update (buf, freq_prev); + + Lsp_stability (lspq); + + return; +} + + +void +Lsp_expand_1 (Word16 buf[], /* (i/o) Q13 : LSP vectors */ + Word16 gap /* (i) Q13 : gap */ + ) +{ + Word16 j, tmp; + Word16 diff; /* Q13 */ + + for (j = 1; j < NC; j++) { + diff = sub (buf[j - 1], buf[j]); + tmp = shr (add (diff, gap), 1); + + if (tmp > 0) { + buf[j - 1] = sub (buf[j - 1], tmp); + buf[j] = add (buf[j], tmp); + } + } + return; +} + + +void +Lsp_expand_2 (Word16 buf[], /* (i/o) Q13 : LSP vectors */ + Word16 gap /* (i) Q13 : gap */ + ) +{ + Word16 j, tmp; + Word16 diff; /* Q13 */ + + for (j = NC; j < M; j++) { + diff = sub (buf[j - 1], buf[j]); + tmp = shr (add (diff, gap), 1); + + if (tmp > 0) { + buf[j - 1] = sub (buf[j - 1], tmp); + buf[j] = add (buf[j], tmp); + } + } + return; +} + + +void +Lsp_expand_1_2 (Word16 buf[], /* (i/o) Q13 : LSP vectors */ + Word16 gap /* (i) Q13 : gap */ + ) +{ + Word16 j, tmp; + Word16 diff; /* Q13 */ + + for (j = 1; j < M; j++) { + diff = sub (buf[j - 1], buf[j]); + tmp = shr (add (diff, gap), 1); + + if (tmp > 0) { + buf[j - 1] = sub (buf[j - 1], tmp); + buf[j] = add (buf[j], tmp); + } + } + return; +} + + +/* + Functions which use previous LSP parameter (freq_prev). +*/ + + +/* + compose LSP parameter from elementary LSP with previous LSP. +*/ +void +Lsp_prev_compose (Word16 lsp_ele[], /* (i) Q13 : LSP vectors */ + Word16 lsp[], /* (o) Q13 : quantized LSP parameters */ + Word16 fg[][M], /* (i) Q15 : MA prediction coef. */ + Word16 freq_prev[][M], /* (i) Q13 : previous LSP vector */ + Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */ + ) +{ + Word16 j, k; + Word32 L_acc; /* Q29 */ + + for (j = 0; j < M; j++) { + L_acc = L_mult (lsp_ele[j], fg_sum[j]); + for (k = 0; k < MA_NP; k++) + L_acc = L_mac (L_acc, freq_prev[k][j], fg[k][j]); + + lsp[j] = extract_h (L_acc); + } + return; +} + + +/* + extract elementary LSP from composed LSP with previous LSP +*/ +void +Lsp_prev_extract (Word16 lsp[M], /* (i) Q13 : unquantized LSP parameters */ + Word16 lsp_ele[M], /* (o) Q13 : target vector */ + Word16 fg[MA_NP][M], /* (i) Q15 : MA prediction coef. */ + Word16 freq_prev[MA_NP][M], /* (i) Q13 : previous LSP vector */ + Word16 fg_sum_inv[M] /* (i) Q12 : inverse previous LSP vector */ + ) +{ + Word16 j, k; + Word32 L_temp; /* Q19 */ + Word16 temp; /* Q13 */ + + + for (j = 0; j < M; j++) { + L_temp = L_deposit_h (lsp[j]); + for (k = 0; k < MA_NP; k++) + L_temp = L_msu (L_temp, freq_prev[k][j], fg[k][j]); + + temp = extract_h (L_temp); + L_temp = L_mult (temp, fg_sum_inv[j]); + lsp_ele[j] = extract_h (L_shl (L_temp, 3)); + + } + return; +} + + +/* + update previous LSP parameter +*/ +void +Lsp_prev_update (Word16 lsp_ele[M], /* (i) Q13 : LSP vectors */ + Word16 freq_prev[MA_NP][M] /* (i/o) Q13 : previous LSP vectors */ + ) +{ + Word16 k; + + for (k = MA_NP - 1; k > 0; k--) + Copy (freq_prev[k - 1], freq_prev[k], M); + + Copy (lsp_ele, freq_prev[0], M); + return; +} + +void +Lsp_stability (Word16 buf[] /* (i/o) Q13 : quantized LSP parameters */ + ) +{ + Word16 j; + Word16 tmp; + Word32 L_diff; + Word32 L_acc, L_accb; + + for (j = 0; j < M - 1; j++) { + L_acc = L_deposit_l (buf[j + 1]); + L_accb = L_deposit_l (buf[j]); + L_diff = L_sub (L_acc, L_accb); + + if (L_diff < 0L) { + /* exchange buf[j]<->buf[j+1] */ + tmp = buf[j + 1]; + buf[j + 1] = buf[j]; + buf[j] = tmp; + } + } + + + if (sub (buf[0], L_LIMIT) < 0) { + buf[0] = L_LIMIT; + printf ("lsp_stability warning Low \n"); + } + for (j = 0; j < M - 1; j++) { + L_acc = L_deposit_l (buf[j + 1]); + L_accb = L_deposit_l (buf[j]); + L_diff = L_sub (L_acc, L_accb); + + if (L_sub (L_diff, GAP3) < 0L) { + buf[j + 1] = add (buf[j], GAP3); + } + } + + if (sub (buf[M - 1], M_LIMIT) > 0) { + buf[M - 1] = M_LIMIT; + printf ("lsp_stability warning High \n"); + } + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/lspgetq.h asterisk-1.2.1/codecs/g729a_v11/lspgetq.h --- asterisk-1.2.1.ori/codecs/g729a_v11/lspgetq.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/lspgetq.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,50 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +void Lsp_get_quant (Word16 lspcb1[][M], /* Q13 */ + Word16 lspcb2[][M], /* Q13 */ + Word16 code0, Word16 code1, Word16 code2, Word16 fg[][M], /* Q15 */ + Word16 freq_prev[][M], /* Q13 */ + Word16 lspq[], /* Q13 */ + Word16 fg_sum[] /* Q15 */ + ); + +void Lsp_expand_1 (Word16 buf[], /* Q13 */ + Word16 gap /* Q13 */ + ); + +void Lsp_expand_2 (Word16 buf[], /* Q13 */ + Word16 gap /* Q13 */ + ); + +void Lsp_expand_1_2 (Word16 buf[], /* Q13 */ + Word16 gap /* Q13 */ + ); + +void Lsp_stability (Word16 buf[] /* Q13 */ + ); + +void Lsp_prev_compose (Word16 lsp_ele[], /* Q13 */ + Word16 lsp[], /* Q13 */ + Word16 fg[][M], /* Q15 */ + Word16 freq_prev[][M], /* Q13 */ + Word16 fg_sum[] /* Q15 */ + ); + +void Lsp_prev_extract (Word16 lsp[M], /* Q13 */ + Word16 lsp_ele[M], /* Q13 */ + Word16 fg[MA_NP][M], /* Q15 */ + Word16 freq_prev[MA_NP][M], /* Q13 */ + Word16 fg_sum_inv[M] /* Q12 */ + ); + +void Lsp_prev_update (Word16 lsp_ele[M], /* Q13 */ + Word16 freq_prev[MA_NP][M] /* Q13 */ + ); + diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/oper_32b.c asterisk-1.2.1/codecs/g729a_v11/oper_32b.c --- asterisk-1.2.1.ori/codecs/g729a_v11/oper_32b.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/oper_32b.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,228 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" + +/*___________________________________________________________________________ + | | + | This file contains operations in double precision. | + | These operations are not standard double precision operations. | + | They are used where single precision is not enough but the full 32 bits | + | precision is not necessary. For example, the function Div_32() has a | + | 24 bits precision which is enough for our purposes. | + | | + | The double precision numbers use a special representation: | + | | + | L_32 = hi<<16 + lo<<1 | + | | + | L_32 is a 32 bit integer. | + | hi and lo are 16 bit signed integers. | + | As the low part also contains the sign, this allows fast multiplication. | + | | + | 0x8000 0000 <= L_32 <= 0x7fff fffe. | + | | + | We will use DPF (Double Precision Format )in this file to specify | + | this special format. | + |___________________________________________________________________________| +*/ + +/*___________________________________________________________________________ + | | + | Function L_Extract() | + | | + | Extract from a 32 bit integer two 16 bit DPF. | + | | + | Arguments: | + | | + | L_32 : 32 bit integer. | + | 0x8000 0000 <= L_32 <= 0x7fff ffff. | + | hi : b16 to b31 of L_32 | + | lo : (L_32 - hi<<16)>>1 | + |___________________________________________________________________________| +*/ + +void +L_Extract (Word32 L_32, Word16 * hi, Word16 * lo) +{ + *hi = extract_h (L_32); + *lo = extract_l (L_msu (L_shr (L_32, 1), *hi, 16384)); /* lo = L_32>>1 */ + return; +} + +/*___________________________________________________________________________ + | | + | Function L_Comp() | + | | + | Compose from two 16 bit DPF a 32 bit integer. | + | | + | L_32 = hi<<16 + lo<<1 | + | | + | Arguments: | + | | + | hi msb | + | lo lsf (with sign) | + | | + | Return Value : | + | | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x8000 0000 <= L_32 <= 0x7fff fff0. | + | | + |___________________________________________________________________________| +*/ + +Word32 +L_Comp (Word16 hi, Word16 lo) +{ + Word32 L_32; + + L_32 = L_deposit_h (hi); + return (L_mac (L_32, lo, 1)); /* = hi<<16 + lo<<1 */ +} + +/*___________________________________________________________________________ + | Function Mpy_32() | + | | + | Multiply two 32 bit integers (DPF). The result is divided by 2**31 | + | | + | L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 | + | | + | This operation can also be viewed as the multiplication of two Q31 | + | number and the result is also in Q31. | + | | + | Arguments: | + | | + | hi1 hi part of first number | + | lo1 lo part of first number | + | hi2 hi part of second number | + | lo2 lo part of second number | + | | + |___________________________________________________________________________| +*/ + +Word32 +Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2) +{ + Word32 L_32; + + L_32 = L_mult (hi1, hi2); + L_32 = L_mac (L_32, mult (hi1, lo2), 1); + L_32 = L_mac (L_32, mult (lo1, hi2), 1); + + return (L_32); +} + +/*___________________________________________________________________________ + | Function Mpy_32_16() | + | | + | Multiply a 16 bit integer by a 32 bit (DPF). The result is divided | + | by 2**15 | + | | + | This operation can also be viewed as the multiplication of a Q31 | + | number by a Q15 number, the result is in Q31. | + | | + | L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 | + | | + | Arguments: | + | | + | hi hi part of 32 bit number. | + | lo lo part of 32 bit number. | + | n 16 bit number. | + | | + |___________________________________________________________________________| +*/ + +Word32 +Mpy_32_16 (Word16 hi, Word16 lo, Word16 n) +{ + Word32 L_32; + + L_32 = L_mult (hi, n); + L_32 = L_mac (L_32, mult (lo, n), 1); + + return (L_32); +} + +/*___________________________________________________________________________ + | | + | Function Name : Div_32 | + | | + | Purpose : | + | Fractional integer division of two 32 bit numbers. | + | L_num / L_denom. | + | L_num and L_denom must be positive and L_num < L_denom. | + | L_denom = denom_hi<<16 + denom_lo<<1 | + | denom_hi is a normalize number. | + | The result is in Q30. | + | | + | Inputs : | + | | + | L_num | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x0000 0000 < L_num < L_denom | + | | + | L_denom = denom_hi<<16 + denom_lo<<1 (DPF) | + | | + | denom_hi | + | 16 bit positive normalized integer whose value falls in the | + | range : 0x4000 < hi < 0x7fff | + | denom_lo | + | 16 bit positive integer whose value falls in the | + | range : 0 < lo < 0x7fff | + | | + | Return Value : | + | | + | L_div | + | 32 bit long signed integer (Word32) whose value falls in the | + | range : 0x0000 0000 <= L_div <= 0x7fff ffff. | + | It's a Q31 value | + | | + | Algorithm: | + | | + | - find = 1/L_denom. | + | First approximation: approx = 1 / denom_hi | + | 1/L_denom = approx * (2.0 - L_denom * approx ) | + | | + | - result = L_num * (1/L_denom) | + |___________________________________________________________________________| +*/ + +Word32 +Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo) +{ + Word16 approx, hi, lo, n_hi, n_lo; + Word32 L_32; + + + /* First approximation: 1 / L_denom = 1/denom_hi */ + + approx = div_s ((Word16) 0x3fff, denom_hi); /* result in Q14 */ + /* Note: 3fff = 0.5 in Q15 */ + + /* 1/L_denom = approx * (2.0 - L_denom * approx) */ + + L_32 = Mpy_32_16 (denom_hi, denom_lo, approx); /* result in Q30 */ + + + L_32 = L_sub ((Word32) 0x7fffffffL, L_32); /* result in Q30 */ + + L_Extract (L_32, &hi, &lo); + + L_32 = Mpy_32_16 (hi, lo, approx); /* = 1/L_denom in Q29 */ + + /* L_num * (1/L_denom) */ + + L_Extract (L_32, &hi, &lo); + L_Extract (L_num, &n_hi, &n_lo); + L_32 = Mpy_32 (n_hi, n_lo, hi, lo); /* result in Q29 */ + L_32 = L_shl (L_32, 2); /* From Q29 to Q31 */ + + return (L_32); +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/oper_32b.h asterisk-1.2.1/codecs/g729a_v11/oper_32b.h --- asterisk-1.2.1.ori/codecs/g729a_v11/oper_32b.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/oper_32b.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,16 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/* Double precision operations */ + +void L_Extract (Word32 L_32, Word16 * hi, Word16 * lo); +Word32 L_Comp (Word16 hi, Word16 lo); +Word32 Mpy_32 (Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2); +Word32 Mpy_32_16 (Word16 hi, Word16 lo, Word16 n); +Word32 Div_32 (Word32 L_num, Word16 denom_hi, Word16 denom_lo); diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/p_parity.c asterisk-1.2.1/codecs/g729a_v11/p_parity.c --- asterisk-1.2.1.ori/codecs/g729a_v11/p_parity.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/p_parity.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,63 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------* + * Parity_pitch - compute parity bit for first 6 MSBs * + *------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" + +Word16 +Parity_Pitch ( /* output: parity bit (XOR of 6 MSB bits) */ + Word16 pitch_index /* input : index for which parity to compute */ + ) +{ + Word16 temp, sum, i, bit; + + temp = shr (pitch_index, 1); + + sum = 1; + for (i = 0; i <= 5; i++) { + temp = shr (temp, 1); + bit = temp & (Word16) 1; + sum = add (sum, bit); + } + sum = sum & (Word16) 1; + + + return sum; +} + +/*--------------------------------------------------------------------* + * check_parity_pitch - check parity of index with transmitted parity * + *--------------------------------------------------------------------*/ + +Word16 +Check_Parity_Pitch ( /* output: 0 = no error, 1= error */ + Word16 pitch_index, /* input : index of parameter */ + Word16 parity /* input : parity bit */ + ) +{ + Word16 temp, sum, i, bit; + + temp = shr (pitch_index, 1); + + sum = 1; + for (i = 0; i <= 5; i++) { + temp = shr (temp, 1); + bit = temp & (Word16) 1; + sum = add (sum, bit); + } + sum = add (sum, parity); + sum = sum & (Word16) 1; + + return sum; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/pitch_a.c asterisk-1.2.1/codecs/g729a_v11/pitch_a.c --- asterisk-1.2.1.ori/codecs/g729a_v11/pitch_a.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/pitch_a.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,570 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*---------------------------------------------------------------------------* + * Pitch related functions * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + *---------------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "ld8a.h" +#include "tab_ld8a.h" +#include "util.h" + +/*---------------------------------------------------------------------------* + * Function Pitch_ol_fast * + * ~~~~~~~~~~~~~~~~~~~~~~~ * + * Compute the open loop pitch lag. (fast version) * + * * + *---------------------------------------------------------------------------*/ + + +Word16 +Pitch_ol_fast ( /* output: open loop pitch lag */ + Word16 signal[], /* input : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_max, /* input : maximum pitch lag */ + Word16 L_frame /* input : length of frame to compute pitch */ + ) +{ + Flag Overflow; + Word16 i, j; + Word16 max1, max2, max3; + Word16 max_h, max_l, ener_h, ener_l; + Word16 T1, T2, T3; + Word16 *p, *p1; + Word32 max, sum, L_temp; + + /* Scaled signal */ + + Word16 scaled_signal[L_FRAME + PIT_MAX]; + Word16 *scal_sig; + + scal_sig = &scaled_signal[pit_max]; + + /*--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------*/ + + Overflow = 0; + sum = 0; + + for (i = -pit_max; i < L_frame; i += 2) + sum = L_mac_o (sum, signal[i], signal[i], &Overflow); + + /*--------------------------------------------------------* + * Scaling of input signal. * + * * + * if Overflow -> scal_sig[i] = signal[i]>>3 * + * else if sum < 1^20 -> scal_sig[i] = signal[i]<<3 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------*/ + + if (Overflow == 1) { + for (i = -pit_max; i < L_frame; i++) { + scal_sig[i] = shr (signal[i], 3); + } + } + else { + L_temp = L_sub (sum, (Word32) 1048576L); + if (L_temp < (Word32) 0) { /* if (sum < 2^20) */ + for (i = -pit_max; i < L_frame; i++) { + scal_sig[i] = shl (signal[i], 3); + } + } + else { + for (i = -pit_max; i < L_frame; i++) { + scal_sig[i] = signal[i]; + } + } + } + + /*--------------------------------------------------------------------* + * The pitch lag search is divided in three sections. * + * Each section cannot have a pitch multiple. * + * We find a maximum for each section. * + * We compare the maxima of each section by favoring small lag. * + * * + * First section: lag delay = 20 to 39 * + * Second section: lag delay = 40 to 79 * + * Third section: lag delay = 80 to 143 * + *--------------------------------------------------------------------*/ + + /* First section */ + + max = MIN_32; + T1 = 20; /* Only to remove warning from some compilers */ + for (i = 20; i < 40; i++) { + p = scal_sig; + p1 = &scal_sig[-i]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T1 = i; + } + } + + /* compute energy of maximum */ + + sum = 1; /* to avoid division by zero */ + p = &scal_sig[-T1]; + for (i = 0; i < L_frame; i += 2, p += 2) + sum = L_mac (sum, *p, *p); + + /* max1 = max/sqrt(energy) */ + /* This result will always be on 16 bits !! */ + + sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */ + L_Extract (max, &max_h, &max_l); + L_Extract (sum, &ener_h, &ener_l); + sum = Mpy_32 (max_h, max_l, ener_h, ener_l); + max1 = extract_l (sum); + + /* Second section */ + + max = MIN_32; + T2 = 40; /* Only to remove warning from some compilers */ + for (i = 40; i < 80; i++) { + p = scal_sig; + p1 = &scal_sig[-i]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T2 = i; + } + } + + /* compute energy of maximum */ + + sum = 1; /* to avoid division by zero */ + p = &scal_sig[-T2]; + for (i = 0; i < L_frame; i += 2, p += 2) + sum = L_mac (sum, *p, *p); + + /* max2 = max/sqrt(energy) */ + /* This result will always be on 16 bits !! */ + + sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */ + L_Extract (max, &max_h, &max_l); + L_Extract (sum, &ener_h, &ener_l); + sum = Mpy_32 (max_h, max_l, ener_h, ener_l); + max2 = extract_l (sum); + + /* Third section */ + + max = MIN_32; + T3 = 80; /* Only to remove warning from some compilers */ + for (i = 80; i < 143; i += 2) { + p = scal_sig; + p1 = &scal_sig[-i]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T3 = i; + } + } + + /* Test around max3 */ + + i = T3; + p = scal_sig; + p1 = &scal_sig[-(i + 1)]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T3 = i + (Word16) 1; + } + + p = scal_sig; + p1 = &scal_sig[-(i - 1)]; + sum = 0; + for (j = 0; j < L_frame; j += 2, p += 2, p1 += 2) + sum = L_mac (sum, *p, *p1); + L_temp = L_sub (sum, max); + if (L_temp > 0) { + max = sum; + T3 = i - (Word16) 1; + } + + /* compute energy of maximum */ + + sum = 1; /* to avoid division by zero */ + p = &scal_sig[-T3]; + for (i = 0; i < L_frame; i += 2, p += 2) + sum = L_mac (sum, *p, *p); + + /* max1 = max/sqrt(energy) */ + /* This result will always be on 16 bits !! */ + + sum = Inv_sqrt (sum); /* 1/sqrt(energy), result in Q30 */ + L_Extract (max, &max_h, &max_l); + L_Extract (sum, &ener_h, &ener_l); + sum = Mpy_32 (max_h, max_l, ener_h, ener_l); + max3 = extract_l (sum); + + /*-----------------------* + * Test for multiple. * + *-----------------------*/ + + /* if( abs(T2*2 - T3) < 5) */ + /* max2 += max3 * 0.25; */ + + i = sub (shl (T2, 1), T3); + j = sub (abs_s (i), 5); + if (j < 0) + max2 = add (max2, shr (max3, 2)); + + /* if( abs(T2*3 - T3) < 7) */ + /* max2 += max3 * 0.25; */ + + i = add (i, T2); + j = sub (abs_s (i), 7); + if (j < 0) + max2 = add (max2, shr (max3, 2)); + + /* if( abs(T1*2 - T2) < 5) */ + /* max1 += max2 * 0.20; */ + + i = sub (shl (T1, 1), T2); + j = sub (abs_s (i), 5); + if (j < 0) + max1 = add (max1, mult (max2, 6554)); + + /* if( abs(T1*3 - T2) < 7) */ + /* max1 += max2 * 0.20; */ + + i = add (i, T1); + j = sub (abs_s (i), 7); + if (j < 0) + max1 = add (max1, mult (max2, 6554)); + + /*--------------------------------------------------------------------* + * Compare the 3 sections maxima. * + *--------------------------------------------------------------------*/ + + if (sub (max1, max2) < 0) { + max1 = max2; + T1 = T2; + } + if (sub (max1, max3) < 0) { + T1 = T3; + } + + return T1; +} + + + + +/*--------------------------------------------------------------------------* + * Function Dot_Product() * + * ~~~~~~~~~~~~~~~~~~~~~~ * + *--------------------------------------------------------------------------*/ + +Word32 +Dot_Product ( /* (o) :Result of scalar product. */ + Word16 x[], /* (i) :First vector. */ + Word16 y[], /* (i) :Second vector. */ + Word16 lg /* (i) :Number of point. */ + ) +{ + Word16 i; + Word32 sum; + + sum = 0; + for (i = 0; i < lg; i++) + sum = L_mac (sum, x[i], y[i]); + + return sum; +} + +/*--------------------------------------------------------------------------* + * Function Pitch_fr3_fast() * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * Fast version of the pitch close loop. * + *--------------------------------------------------------------------------*/ + +Word16 +Pitch_fr3_fast ( /* (o) : pitch period. */ + Word16 exc[], /* (i) : excitation buffer */ + Word16 xn[], /* (i) : target vector */ + Word16 h[], /* (i) Q12 : impulse response of filters. */ + Word16 L_subfr, /* (i) : Length of subframe */ + Word16 t0_min, /* (i) : minimum value in the searched range. */ + Word16 t0_max, /* (i) : maximum value in the searched range. */ + Word16 i_subfr, /* (i) : indicator for first subframe. */ + Word16 * pit_frac /* (o) : chosen fraction. */ + ) +{ + Word16 t, t0; + Word16 Dn[L_SUBFR]; + Word16 exc_tmp[L_SUBFR]; + Word32 max, corr, L_temp; + + /*-----------------------------------------------------------------* + * Compute correlation of target vector with impulse response. * + *-----------------------------------------------------------------*/ + + Cor_h_X (h, xn, Dn); + + /*-----------------------------------------------------------------* + * Find maximum integer delay. * + *-----------------------------------------------------------------*/ + + max = MIN_32; + t0 = t0_min; /* Only to remove warning from some compilers */ + + for (t = t0_min; t <= t0_max; t++) { + corr = Dot_Product (Dn, &exc[-t], L_subfr); + L_temp = L_sub (corr, max); + if (L_temp > 0) { + max = corr; + t0 = t; + } + } + + /*-----------------------------------------------------------------* + * Test fractions. * + *-----------------------------------------------------------------*/ + + /* Fraction 0 */ + + Pred_lt_3 (exc, t0, 0, L_subfr); + max = Dot_Product (Dn, exc, L_subfr); + *pit_frac = 0; + + /* If first subframe and lag > 84 do not search fractional pitch */ + + if ((i_subfr == 0) && (sub (t0, 84) > 0)) + return t0; + + Copy (exc, exc_tmp, L_subfr); + + /* Fraction -1/3 */ + + Pred_lt_3 (exc, t0, -1, L_subfr); + corr = Dot_Product (Dn, exc, L_subfr); + L_temp = L_sub (corr, max); + if (L_temp > 0) { + max = corr; + *pit_frac = -1; + Copy (exc, exc_tmp, L_subfr); + } + + /* Fraction +1/3 */ + + Pred_lt_3 (exc, t0, 1, L_subfr); + corr = Dot_Product (Dn, exc, L_subfr); + L_temp = L_sub (corr, max); + if (L_temp > 0) { + max = corr; + *pit_frac = 1; + } + else + Copy (exc_tmp, exc, L_subfr); + + return t0; +} + + +/*---------------------------------------------------------------------* + * Function G_pitch: * + * ~~~~~~~~ * + *---------------------------------------------------------------------* + * Compute correlations and to use in gains quantizer. * + * Also compute the gain of pitch. Result in Q14 * + * if (gain < 0) gain =0 * + * if (gain >1.2) gain =1.2 * + *---------------------------------------------------------------------*/ + + +Word16 +G_pitch ( /* (o) Q14 : Gain of pitch lag saturated to 1.2 */ + Word16 xn[], /* (i) : Pitch target. */ + Word16 y1[], /* (i) : Filtered adaptive codebook. */ + Word16 g_coeff[], /* (i) : Correlations need for gain quantization. */ + Word16 L_subfr /* (i) : Length of subframe. */ + ) +{ + Flag Overflow; + Word16 i; + Word16 xy, yy, exp_xy, exp_yy, gain; + Word32 s; + + Word16 scaled_y1[L_SUBFR]; + + /* divide "y1[]" by 4 to avoid overflow */ + + for (i = 0; i < L_subfr; i++) + scaled_y1[i] = shr (y1[i], 2); + + /* Compute scalar product */ + + Overflow = 0; + s = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_subfr; i++) + s = L_mac_o (s, y1[i], y1[i], &Overflow); + + if (Overflow == 0) { + exp_yy = norm_l (s); + yy = wround (L_shl (s, exp_yy)); + } + else { + s = 1; /* Avoid case of all zeros */ + for (i = 0; i < L_subfr; i++) + s = L_mac (s, scaled_y1[i], scaled_y1[i]); + exp_yy = norm_l (s); + yy = wround (L_shl (s, exp_yy)); + exp_yy = sub (exp_yy, 4); + } + + /* Compute scalar product */ + + Overflow = 0; + s = 0; + for (i = 0; i < L_subfr; i++) + s = L_mac_o (s, xn[i], y1[i], &Overflow); + + if (Overflow == 0) { + exp_xy = norm_l (s); + xy = wround (L_shl (s, exp_xy)); + } + else { + s = 0; + for (i = 0; i < L_subfr; i++) + s = L_mac (s, xn[i], scaled_y1[i]); + exp_xy = norm_l (s); + xy = wround (L_shl (s, exp_xy)); + exp_xy = sub (exp_xy, 2); + } + + g_coeff[0] = yy; + g_coeff[1] = sub (15, exp_yy); + g_coeff[2] = xy; + g_coeff[3] = sub (15, exp_xy); + + /* If (xy <= 0) gain = 0 */ + + + if (xy <= 0) { + g_coeff[3] = -15; /* Force exp_xy to -15 = (15-30) */ + return ((Word16) 0); + } + + /* compute gain = xy/yy */ + + xy = shr (xy, 1); /* Be sure xy < yy */ + gain = div_s (xy, yy); + + i = sub (exp_xy, exp_yy); + gain = shr (gain, i); /* saturation if > 1.99 in Q14 */ + + /* if(gain >1.2) gain = 1.2 in Q14 */ + + if (sub (gain, 19661) > 0) { + gain = 19661; + } + + + return (gain); +} + + + +/*----------------------------------------------------------------------* + * Function Enc_lag3 * + * ~~~~~~~~ * + * Encoding of fractional pitch lag with 1/3 resolution. * + *----------------------------------------------------------------------* + * The pitch range for the first subframe is divided as follows: * + * 19 1/3 to 84 2/3 resolution 1/3 * + * 85 to 143 resolution 1 * + * * + * The period in the first subframe is encoded with 8 bits. * + * For the range with fractions: * + * index = (T-19)*3 + frac - 1; where T=[19..85] and frac=[-1,0,1] * + * and for the integer only range * + * index = (T - 85) + 197; where T=[86..143] * + *----------------------------------------------------------------------* + * For the second subframe a resolution of 1/3 is always used, and the * + * search range is relative to the lag in the first subframe. * + * If t0 is the lag in the first subframe then * + * t_min=t0-5 and t_max=t0+4 and the range is given by * + * t_min - 2/3 to t_max + 2/3 * + * * + * The period in the 2nd subframe is encoded with 5 bits: * + * index = (T-(t_min-1))*3 + frac - 1; where T[t_min-1 .. t_max+1] * + *----------------------------------------------------------------------*/ + + +Word16 +Enc_lag3 ( /* output: Return index of encoding */ + Word16 T0, /* input : Pitch delay */ + Word16 T0_frac, /* input : Fractional pitch delay */ + Word16 * T0_min, /* in/out: Minimum search delay */ + Word16 * T0_max, /* in/out: Maximum search delay */ + Word16 pit_min, /* input : Minimum pitch delay */ + Word16 pit_max, /* input : Maximum pitch delay */ + Word16 pit_flag /* input : Flag for 1st subframe */ + ) +{ + Word16 index, i; + + if (pit_flag == 0) { /* if 1st subframe */ + /* encode pitch delay (with fraction) */ + + if (sub (T0, 85) <= 0) { + /* index = t0*3 - 58 + t0_frac */ + i = add (add (T0, T0), T0); + index = add (sub (i, 58), T0_frac); + } + else { + index = add (T0, 112); + } + + /* find T0_min and T0_max for second subframe */ + + *T0_min = sub (T0, 5); + if (sub (*T0_min, pit_min) < 0) { + *T0_min = pit_min; + } + + *T0_max = add (*T0_min, 9); + if (sub (*T0_max, pit_max) > 0) { + *T0_max = pit_max; + *T0_min = sub (*T0_max, 9); + } + } + else { /* if second subframe */ + + + /* i = t0 - t0_min; */ + /* index = i*3 + 2 + t0_frac; */ + i = sub (T0, *T0_min); + i = add (add (i, i), i); + index = add (add (i, 2), T0_frac); + } + + + return index; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/post_pro.c asterisk-1.2.1/codecs/g729a_v11/post_pro.c --- asterisk-1.2.1.ori/codecs/g729a_v11/post_pro.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/post_pro.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,84 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * Function Post_Process() * + * * + * Post-processing of output speech. * + * - 2nd order high pass filter with cut off frequency at 100 Hz. * + * - Multiplication by two of output speech with saturation. * + *-----------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" + +#include "ld8a.h" +#include "tab_ld8a.h" + +/*------------------------------------------------------------------------* + * 2nd order high pass filter with cut off frequency at 100 Hz. * + * Designed with SPPACK efi command -40 dB att, 0.25 ri. * + * * + * Algorithm: * + * * + * y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] * + * + a[1]*y[i-1] + a[2]*y[i-2]; * + * * + * b[3] = {0.93980581E+00, -0.18795834E+01, 0.93980581E+00}; * + * a[3] = {0.10000000E+01, 0.19330735E+01, -0.93589199E+00}; * + *-----------------------------------------------------------------------*/ + + +/* Initialization of values */ + +void +Init_Post_Process (DecState *decoder) +{ + decoder->y2_hi = 0; + decoder->y2_lo = 0; + decoder->y1_hi = 0; + decoder->y1_lo = 0; + decoder->x0 = 0; + decoder->x1 = 0; +} + + +void +Post_Process (DecState *decoder, + Word16 signal[], /* input/output signal */ + Word16 lg) +{ /* length of signal */ + Word16 i, x2; + Word32 L_tmp; + + for (i = 0; i < lg; i++) { + x2 = decoder->x1; + decoder->x1 = decoder->x0; + decoder->x0 = signal[i]; + + /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */ + /* + a[1]*y[i-1] + a[2] * y[i-2]; */ + + L_tmp = Mpy_32_16 (decoder->y1_hi, decoder->y1_lo, a100[1]); + L_tmp = L_add (L_tmp, Mpy_32_16 (decoder->y2_hi, decoder->y2_lo, a100[2])); + L_tmp = L_mac (L_tmp, decoder->x0, b100[0]); + L_tmp = L_mac (L_tmp, decoder->x1, b100[1]); + L_tmp = L_mac (L_tmp, x2, b100[2]); + L_tmp = L_shl (L_tmp, 2); /* Q29 --> Q31 (Q13 --> Q15) */ + + /* Multiplication by two of output speech with saturation. */ + signal[i] = wround (L_shl (L_tmp, 1)); + + decoder->y2_hi = decoder->y1_hi; + decoder->y2_lo = decoder->y1_lo; + L_Extract (L_tmp, &decoder->y1_hi, &decoder->y1_lo); + } + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/postfilt.c asterisk-1.2.1/codecs/g729a_v11/postfilt.c --- asterisk-1.2.1.ori/codecs/g729a_v11/postfilt.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/postfilt.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,441 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * POSTFILTER.C * + *------------------------------------------------------------------------* + * Performs adaptive postfiltering on the synthesis speech * + * This file contains all functions related to the post filter. * + *------------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "oper_32b.h" +#include "util.h" + +/*---------------------------------------------------------------* + * Postfilter constant parameters (defined in "ld8a.h") * + *---------------------------------------------------------------* + * L_FRAME : Frame size. * + * L_SUBFR : Sub-frame size. * + * M : LPC order. * + * MP1 : LPC order+1 * + * PIT_MAX : Maximum pitch lag. * + * GAMMA2_PST : Formant postfiltering factor (numerator) * + * GAMMA1_PST : Formant postfiltering factor (denominator) * + * GAMMAP : Harmonic postfiltering factor * + * MU : Factor for tilt compensation filter * + * AGC_FAC : Factor for automatic gain control * + *---------------------------------------------------------------*/ + + +/*------------------------------------------------------------* + * vectors * + *------------------------------------------------------------*/ + +/* inverse filtered synthesis (with A(z/GAMMA2_PST)) */ + +/*---------------------------------------------------------------* + * Procedure Init_Post_Filter: * + * ~~~~~~~~~~~~~~~~ * + * Initializes the postfilter parameters: * + *---------------------------------------------------------------*/ + +void +Init_Post_Filter (DecState *decoder) +{ + decoder->res2 = decoder->res2_buf + PIT_MAX; + decoder->scal_res2 = decoder->scal_res2_buf + PIT_MAX; + + Set_zero (decoder->mem_syn_pst, M); + Set_zero (decoder->res2_buf, PIT_MAX + L_SUBFR); + Set_zero (decoder->scal_res2_buf, PIT_MAX + L_SUBFR); + + decoder->mem_pre = 0; + decoder->past_gain = 4096; + return; +} + + + + +/*------------------------------------------------------------------------* + * Procedure Post_Filter: * + * ~~~~~~~~~~~ * + *------------------------------------------------------------------------* + * The postfiltering process is described as follows: * + * * + * - inverse filtering of syn[] through A(z/GAMMA2_PST) to get res2[] * + * - use res2[] to compute pitch parameters * + * - perform pitch postfiltering * + * - tilt compensation filtering; 1 - MU*k*z^-1 * + * - synthesis filtering through 1/A(z/GAMMA1_PST) * + * - adaptive gain control * + *------------------------------------------------------------------------*/ + + + +void +Post_Filter (DecState *decoder, + Word16 * syn, /* in/out: synthesis speech (postfiltered is output) */ + Word16 * Az_4, /* input : interpolated LPC parameters in all subframes */ + Word16 * T /* input : decoded pitch lags in all subframes */ + ) +{ + /*-------------------------------------------------------------------* + * Declaration of parameters * + *-------------------------------------------------------------------*/ + + Word16 res2_pst[L_SUBFR]; /* res2[] after pitch postfiltering */ + Word16 syn_pst[L_FRAME]; /* post filtered synthesis speech */ + + Word16 Ap3[MP1], Ap4[MP1]; /* bandwidth expanded LP parameters */ + + Word16 *Az; /* pointer to Az_4: */ + /* LPC parameters in each subframe */ + Word16 t0_max, t0_min; /* closed-loop pitch search range */ + Word16 i_subfr; /* index for beginning of subframe */ + + Word16 h[L_H]; + + Word16 i, j; + Word16 temp1, temp2; + Word32 L_tmp; + + /*-----------------------------------------------------* + * Post filtering * + *-----------------------------------------------------*/ + + Az = Az_4; + + for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { + /* Find pitch range t0_min - t0_max */ + + t0_min = sub (*T++, 3); + t0_max = add (t0_min, 6); + if (sub (t0_max, PIT_MAX) > 0) { + t0_max = PIT_MAX; + t0_min = sub (t0_max, 6); + } + + /* Find weighted filter coefficients Ap3[] and ap[4] */ + + Weight_Az (Az, GAMMA2_PST, M, Ap3); + Weight_Az (Az, GAMMA1_PST, M, Ap4); + + /* filtering of synthesis speech by A(z/GAMMA2_PST) to find res2[] */ + + Residu (Ap3, &syn[i_subfr], decoder->res2, L_SUBFR); + + /* scaling of "res2[]" to avoid energy overflow */ + + for (j = 0; j < L_SUBFR; j++) { + decoder->scal_res2[j] = shr (decoder->res2[j], 2); + } + + /* pitch postfiltering */ + + pit_pst_filt (decoder->res2, decoder->scal_res2, t0_min, t0_max, L_SUBFR, res2_pst); + + /* tilt compensation filter */ + + /* impulse response of A(z/GAMMA2_PST)/A(z/GAMMA1_PST) */ + + Copy (Ap3, h, M + 1); + Set_zero (&h[M + 1], L_H - M - 1); + Syn_filt (Ap4, h, h, L_H, &h[M + 1], 0, NULL); + + /* 1st correlation of h[] */ + + L_tmp = L_mult (h[0], h[0]); + for (i = 1; i < L_H; i++) + L_tmp = L_mac (L_tmp, h[i], h[i]); + temp1 = extract_h (L_tmp); + + L_tmp = L_mult (h[0], h[1]); + for (i = 1; i < L_H - 1; i++) + L_tmp = L_mac (L_tmp, h[i], h[i + 1]); + temp2 = extract_h (L_tmp); + + if (temp2 <= 0) { + temp2 = 0; + } + else { + temp2 = mult (temp2, MU); + temp2 = div_s (temp2, temp1); + } + + preemphasis (decoder, res2_pst, temp2, L_SUBFR); + + /* filtering through 1/A(z/GAMMA1_PST) */ + + Syn_filt (Ap4, res2_pst, &syn_pst[i_subfr], L_SUBFR, decoder->mem_syn_pst, 1, NULL); + + /* scale output to input */ + + agc (decoder, &syn[i_subfr], &syn_pst[i_subfr], L_SUBFR); + + /* update res2[] buffer; shift by L_SUBFR */ + + Copy (&decoder->res2[L_SUBFR - PIT_MAX], &decoder->res2[-PIT_MAX], PIT_MAX); + Copy (&decoder->scal_res2[L_SUBFR - PIT_MAX], &decoder->scal_res2[-PIT_MAX], PIT_MAX); + + Az += MP1; + } + + /* update syn[] buffer */ + + Copy (&syn[L_FRAME - M], &syn[-M], M); + + /* overwrite synthesis speech by postfiltered synthesis speech */ + + Copy (syn_pst, syn, L_FRAME); + + return; +} + + + + +/*---------------------------------------------------------------------------* + * procedure pitch_pst_filt * + * ~~~~~~~~~~~~~~~~~~~~~~~~ * + * Find the pitch period around the transmitted pitch and perform * + * harmonic postfiltering. * + * Filtering through (1 + g z^-T) / (1+g) ; g = min(pit_gain*gammap, 1) * + *--------------------------------------------------------------------------*/ + +void +pit_pst_filt (Word16 * signal, /* (i) : input signal */ + Word16 * scal_sig, /* (i) : input signal (scaled, divided by 4) */ + Word16 t0_min, /* (i) : minimum value in the searched range */ + Word16 t0_max, /* (i) : maximum value in the searched range */ + Word16 L_subfr, /* (i) : size of filtering */ + Word16 * signal_pst /* (o) : harmonically postfiltered signal */ + ) +{ + Word16 i, j, t0; + Word16 g0, gain, cmax, en, en0; + Word16 *p, *p1, *deb_sig; + Word32 corr, cor_max, ener, ener0, temp; + Word32 L_temp; + +/*---------------------------------------------------------------------------* + * Compute the correlations for all delays * + * and select the delay which maximizes the correlation * + *---------------------------------------------------------------------------*/ + + deb_sig = &scal_sig[-t0_min]; + cor_max = MIN_32; + t0 = t0_min; /* Only to remove warning from some compilers */ + for (i = t0_min; i <= t0_max; i++) { + corr = 0; + p = scal_sig; + p1 = deb_sig; + for (j = 0; j < L_subfr; j++) + corr = L_mac (corr, *p++, *p1++); + + L_temp = L_sub (corr, cor_max); + if (L_temp > (Word32) 0) { + cor_max = corr; + t0 = i; + } + deb_sig--; + } + + /* Compute the energy of the signal delayed by t0 */ + + ener = 1; + p = scal_sig - t0; + for (i = 0; i < L_subfr; i++, p++) + ener = L_mac (ener, *p, *p); + + /* Compute the signal energy in the present subframe */ + + ener0 = 1; + p = scal_sig; + for (i = 0; i < L_subfr; i++, p++) + ener0 = L_mac (ener0, *p, *p); + + if (cor_max < 0) { + cor_max = 0; + } + + /* scale "cor_max", "ener" and "ener0" on 16 bits */ + + temp = cor_max; + if (ener > temp) { + temp = ener; + } + if (ener0 > temp) { + temp = ener0; + } + j = norm_l (temp); + cmax = wround (L_shl (cor_max, j)); + en = wround (L_shl (ener, j)); + en0 = wround (L_shl (ener0, j)); + + /* prediction gain (dB)= -10 log(1-cor_max*cor_max/(ener*ener0)) */ + + /* temp = (cor_max * cor_max) - (0.5 * ener * ener0) */ + temp = L_mult (cmax, cmax); + temp = L_sub (temp, L_shr (L_mult (en, en0), 1)); + + if (temp < (Word32) 0) { /* if prediction gain < 3 dB *//* switch off pitch postfilter */ + for (i = 0; i < L_subfr; i++) + signal_pst[i] = signal[i]; + return; + } + + if (sub (cmax, en) > 0) { /* if pitch gain > 1 */ + g0 = INV_GAMMAP; + gain = GAMMAP_2; + } + else { + cmax = shr (mult (cmax, GAMMAP), 1); /* cmax(Q14) = cmax(Q15) * GAMMAP */ + en = shr (en, 1); /* Q14 */ + i = add (cmax, en); + if (i > 0) { + gain = div_s (cmax, i); /* gain(Q15) = cor_max/(cor_max+ener) */ + g0 = sub (32767, gain); /* g0(Q15) = 1 - gain */ + } + else { + g0 = 32767; + gain = 0; + } + } + + + for (i = 0; i < L_subfr; i++) { + /* signal_pst[i] = g0*signal[i] + gain*signal[i-t0]; */ + + signal_pst[i] = add (mult (g0, signal[i]), mult (gain, signal[i - t0])); + + } + + return; +} + + +/*---------------------------------------------------------------------* + * routine preemphasis() * + * ~~~~~~~~~~~~~~~~~~~~~ * + * Preemphasis: filtering through 1 - g z^-1 * + *---------------------------------------------------------------------*/ + +void +preemphasis (DecState *decoder, + Word16 * signal, /* (i/o) : input signal overwritten by the output */ + Word16 g, /* (i) Q15 : preemphasis coefficient */ + Word16 L /* (i) : size of filtering */ + ) +{ + Word16 *p1, *p2, temp, i; + + p1 = signal + L - 1; + p2 = p1 - 1; + temp = *p1; + + for (i = 0; i <= L - 2; i++) { + *p1 = sub (*p1, mult (g, *p2)); p1--; p2--; + } + + *p1 = sub (*p1, mult (g, decoder->mem_pre)); + + decoder->mem_pre = temp; + + return; +} + + + +/*----------------------------------------------------------------------* + * routine agc() * + * ~~~~~~~~~~~~~ * + * Scale the postfilter output on a subframe basis by automatic control * + * of the subframe gain. * + * gain[n] = AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out * + *----------------------------------------------------------------------*/ + +void +agc (DecState *decoder, + Word16 * sig_in, /* (i) : postfilter input signal */ + Word16 * sig_out, /* (i/o) : postfilter output signal */ + Word16 l_trm /* (i) : subframe size */ + ) +{ + Word16 i, exp; + Word16 gain_in, gain_out, g0, gain; /* Q12 */ + Word32 s; + + Word16 signal[L_SUBFR]; + + /* calculate gain_out with exponent */ + + for (i = 0; i < l_trm; i++) + signal[i] = shr (sig_out[i], 2); + + s = 0; + for (i = 0; i < l_trm; i++) + s = L_mac (s, signal[i], signal[i]); + + if (s == 0) { + decoder->past_gain = 0; + return; + } + exp = sub (norm_l (s), 1); + gain_out = wround (L_shl (s, exp)); + + /* calculate gain_in with exponent */ + + for (i = 0; i < l_trm; i++) + signal[i] = shr (sig_in[i], 2); + + s = 0; + for (i = 0; i < l_trm; i++) + s = L_mac (s, signal[i], signal[i]); + + if (s == 0) { + g0 = 0; + } + else { + i = norm_l (s); + gain_in = wround (L_shl (s, i)); + exp = sub (exp, i); + + /*---------------------------------------------------* + * g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out); * + *---------------------------------------------------*/ + + s = L_deposit_l (div_s (gain_out, gain_in)); /* Q15 */ + s = L_shl (s, 7); /* s(Q22) = gain_out / gain_in */ + s = L_shr (s, exp); /* Q22, add exponent */ + + /* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */ + s = Inv_sqrt (s); /* Q19 */ + i = wround (L_shl (s, 9)); /* Q12 */ + + /* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */ + g0 = mult (i, AGC_FAC1); /* Q12 */ + } + + /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */ + /* sig_out(n) = gain(n) sig_out(n) */ + + gain = decoder->past_gain; + for (i = 0; i < l_trm; i++) { + gain = mult (gain, AGC_FAC); + gain = add (gain, g0); + sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], gain), 3)); + } + decoder->past_gain = gain; + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/pre_proc.c asterisk-1.2.1/codecs/g729a_v11/pre_proc.c --- asterisk-1.2.1.ori/codecs/g729a_v11/pre_proc.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/pre_proc.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,84 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*------------------------------------------------------------------------* + * Function Pre_Process() * + * * + * Preprocessing of input speech. * + * - 2nd order high pass filter with cut off frequency at 140 Hz. * + * - Divide input by two. * + *-----------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" + +#include "ld8a.h" +#include "tab_ld8a.h" + +/*------------------------------------------------------------------------* + * 2nd order high pass filter with cut off frequency at 140 Hz. * + * Designed with SPPACK efi command -40 dB att, 0.25 ri. * + * * + * Algorithm: * + * * + * y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2 * + * + a[1]*y[i-1] + a[2]*y[i-2]; * + * * + * b[3] = {0.92727435E+00, -0.18544941E+01, 0.92727435E+00}; * + * a[3] = {0.10000000E+01, 0.19059465E+01, -0.91140240E+00}; * + * * + * Input are divided by two in the filtering process. * + *-----------------------------------------------------------------------*/ + + +/* Initialization of values */ + +void +Init_Pre_Process (CodState *coder) +{ + coder->y2_hi = 0; + coder->y2_lo = 0; + coder->y1_hi = 0; + coder->y1_lo = 0; + coder->x0 = 0; + coder->x1 = 0; +} + + +void +Pre_Process (CodState *coder, + Word16 signal[], /* input/output signal */ + Word16 lg) +{ /* length of signal */ + Word16 i, x2; + Word32 L_tmp; + + for (i = 0; i < lg; i++) { + x2 = coder->x1; + coder->x1 = coder->x0; + coder->x0 = signal[i]; + + /* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 */ + /* + a[1]*y[i-1] + a[2] * y[i-2]; */ + + L_tmp = Mpy_32_16 (coder->y1_hi, coder->y1_lo, a140[1]); + L_tmp = L_add (L_tmp, Mpy_32_16 (coder->y2_hi, coder->y2_lo, a140[2])); + L_tmp = L_mac (L_tmp, coder->x0, b140[0]); + L_tmp = L_mac (L_tmp, coder->x1, b140[1]); + L_tmp = L_mac (L_tmp, x2, b140[2]); + L_tmp = L_shl (L_tmp, 3); /* Q28 --> Q31 (Q12 --> Q15) */ + signal[i] = wround (L_tmp); + + coder->y2_hi = coder->y1_hi; + coder->y2_lo = coder->y1_lo; + L_Extract (L_tmp, &coder->y1_hi, &coder->y1_lo); + } + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/pre_proc.h asterisk-1.2.1/codecs/g729a_v11/pre_proc.h --- asterisk-1.2.1.ori/codecs/g729a_v11/pre_proc.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/pre_proc.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,17 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +void Init_Pre_Process (CodState *coder); + +void Pre_Process (CodState *coder, + Word16 signal[], /* Input/output signal */ + Word16 lg /* Length of signal */ ); + + + diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/pred_lt3.c asterisk-1.2.1/codecs/g729a_v11/pred_lt3.c --- asterisk-1.2.1.ori/codecs/g729a_v11/pred_lt3.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/pred_lt3.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,61 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------------* + * Function Pred_lt_3() * + * ~~~~~~~~~~~ * + *-------------------------------------------------------------------* + * Compute the result of long term prediction with fractional * + * interpolation of resolution 1/3. * + * * + * On return exc[0..L_subfr-1] contains the interpolated signal * + * (adaptive codebook excitation) * + *-------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" + +void +Pred_lt_3 (Word16 exc[], /* in/out: excitation buffer */ + Word16 T0, /* input : integer pitch lag */ + Word16 frac, /* input : fraction of lag */ + Word16 L_subfr /* input : subframe size */ + ) +{ + Word16 i, j, k; + Word16 *x0, *x1, *x2, *c1, *c2; + Word32 s; + + x0 = &exc[-T0]; + + frac = negate (frac); + if (frac < 0) { + frac = add (frac, UP_SAMP); + x0--; + } + + for (j = 0; j < L_subfr; j++) { + x1 = x0++; + x2 = x0; + c1 = &inter_3l[frac]; + c2 = &inter_3l[sub (UP_SAMP, frac)]; + + s = 0; + for (i = 0, k = 0; i < L_INTER10; i++, k += UP_SAMP) { + s = L_mac (s, x1[-i], c1[k]); + s = L_mac (s, x2[i], c2[k]); + } + + exc[j] = wround (s); + } + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/qua_gain.c asterisk-1.2.1/codecs/g729a_v11/qua_gain.c --- asterisk-1.2.1.ori/codecs/g729a_v11/qua_gain.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/qua_gain.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,443 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" + +#include "ld8a.h" +#include "tab_ld8a.h" +#include "taming.h" + +void Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */ + /* (i) [1] Q2 : unquantized code gain */ + Word16 * cand1, /* (o) : index of best 1st stage vector */ + Word16 * cand2, /* (o) : index of best 2nd stage vector */ + Word16 gcode0 /* (i) Q4 : presearch for gain codebook */ + ); + + +/*---------------------------------------------------------------------------* + * Function Qua_gain * + * ~~~~~~~~~~~~~~~~~~ * + * Inputs: * + * code[] :Innovative codebook. * + * g_coeff[] :Correlations compute for pitch. * + * L_subfr :Subframe length. * + * * + * Outputs: * + * gain_pit :Quantized pitch gain. * + * gain_cod :Quantized code gain. * + * * + * Return: * + * Index of quantization. * + * * + *--------------------------------------------------------------------------*/ +Word16 +Qua_gain (CodState *coder, + Word16 code[], /* (i) Q13 :Innovative vector. */ + Word16 g_coeff[], /* (i) :Correlations -2 */ + /* , -2, 2 */ + Word16 exp_coeff[], /* (i) :Q-Format g_coeff[] */ + Word16 L_subfr, /* (i) :Subframe length. */ + Word16 * gain_pit, /* (o) Q14 :Pitch gain. */ + Word16 * gain_cod, /* (o) Q1 :Code gain. */ + Word16 tameflag /* (i) : set to 1 if taming is needed */ + ) +{ + Word16 i, j, index1, index2; + Word16 cand1, cand2; + Word16 exp, gcode0, exp_gcode0, gcode0_org, e_min; + Word16 nume, denom, inv_denom; + Word16 exp1, exp2, exp_nume, exp_denom, exp_inv_denom, sft, tmp; + Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod; + Word16 coeff[5], coeff_lsf[5]; + Word16 exp_min[5]; + Word32 L_gbk12; + Word32 L_tmp, L_dist_min, L_temp, L_tmp1, L_tmp2, L_acc, L_accb; + Word16 best_gain[2]; + + /* Gain predictor, Past quantized energies = -14.0 in Q10 */ + + + /*---------------------------------------------------* + *- energy due to innovation -* + *- predicted energy -* + *- predicted codebook gain => gcode0[exp_gcode0] -* + *---------------------------------------------------*/ + + Gain_predict (coder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0); + + /*-----------------------------------------------------------------* + * pre-selection * + *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * calculate best gain * + * * + * tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; * + * best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; * + * best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; * + * gbk_presel(best_gain,&cand1,&cand2,gcode0) ; * + * * + *-----------------------------------------------------------------*/ + + /*-----------------------------------------------------------------* + * tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; * + *-----------------------------------------------------------------*/ + L_tmp1 = L_mult (g_coeff[0], g_coeff[2]); + exp1 = add (add (exp_coeff[0], exp_coeff[2]), 1 - 2); + L_tmp2 = L_mult (g_coeff[4], g_coeff[4]); + exp2 = add (add (exp_coeff[4], exp_coeff[4]), 1); + + if (sub (exp1, exp2) > 0) { + L_tmp = L_sub (L_shr (L_tmp1, sub (exp1, exp2)), L_tmp2); + exp = exp2; + } + else { + L_tmp = L_sub (L_tmp1, L_shr (L_tmp2, sub (exp2, exp1))); + exp = exp1; + } + sft = norm_l (L_tmp); + denom = extract_h (L_shl (L_tmp, sft)); + exp_denom = sub (add (exp, sft), 16); + + inv_denom = div_s (16384, denom); + inv_denom = negate (inv_denom); + exp_inv_denom = sub (14 + 15, exp_denom); + + /*-----------------------------------------------------------------* + * best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; * + *-----------------------------------------------------------------*/ + L_tmp1 = L_mult (g_coeff[2], g_coeff[1]); + exp1 = add (exp_coeff[2], exp_coeff[1]); + L_tmp2 = L_mult (g_coeff[3], g_coeff[4]); + exp2 = add (add (exp_coeff[3], exp_coeff[4]), 1); + + if (sub (exp1, exp2) > 0) { + L_tmp = + L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1)); + exp = sub (exp2, 1); + } + else { + L_tmp = + L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1))); + exp = sub (exp1, 1); + } + sft = norm_l (L_tmp); + nume = extract_h (L_shl (L_tmp, sft)); + exp_nume = sub (add (exp, sft), 16); + + sft = sub (add (exp_nume, exp_inv_denom), (9 + 16 - 1)); + L_acc = L_shr (L_mult (nume, inv_denom), sft); + best_gain[0] = extract_h (L_acc); /*-- best_gain[0]:Q9 --*/ + + if (tameflag == 1) { + if (sub (best_gain[0], GPCLIP2) > 0) + best_gain[0] = GPCLIP2; + } + + /*-----------------------------------------------------------------* + * best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; * + *-----------------------------------------------------------------*/ + L_tmp1 = L_mult (g_coeff[0], g_coeff[3]); + exp1 = add (exp_coeff[0], exp_coeff[3]); + L_tmp2 = L_mult (g_coeff[1], g_coeff[4]); + exp2 = add (add (exp_coeff[1], exp_coeff[4]), 1); + + if (sub (exp1, exp2) > 0) { + L_tmp = + L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1)); + exp = sub (exp2, 1); + } + else { + L_tmp = + L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1))); + exp = sub (exp1, 1); + } + sft = norm_l (L_tmp); + nume = extract_h (L_shl (L_tmp, sft)); + exp_nume = sub (add (exp, sft), 16); + + sft = sub (add (exp_nume, exp_inv_denom), (2 + 16 - 1)); + L_acc = L_shr (L_mult (nume, inv_denom), sft); + best_gain[1] = extract_h (L_acc); /*-- best_gain[1]:Q2 --*/ + + /*--- Change Q-format of gcode0 ( Q[exp_gcode0] -> Q4 ) ---*/ + if (sub (exp_gcode0, 4) >= 0) { + gcode0_org = shr (gcode0, sub (exp_gcode0, 4)); + } + else { + L_acc = L_deposit_l (gcode0); + L_acc = L_shl (L_acc, sub ((4 + 16), exp_gcode0)); + gcode0_org = extract_h (L_acc); /*-- gcode0_org:Q4 --*/ + } + + /*----------------------------------------------* + * - presearch for gain codebook - * + *----------------------------------------------*/ + + Gbk_presel (best_gain, &cand1, &cand2, gcode0_org); + +/*---------------------------------------------------------------------------* + * * + * Find the best quantizer. * + * * + * dist_min = MAX_32; * + * for ( i=0 ; ipast_qua_en, L_gbk12); + + return (add (map1[index1] * (Word16) NCODE2, map2[index2])); + +} + +/*---------------------------------------------------------------------------* + * Function Gbk_presel * + * ~~~~~~~~~~~~~~~~~~~ * + * - presearch for gain codebook - * + *---------------------------------------------------------------------------*/ +void +Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */ + /* (i) [1] Q2 : unquantized code gain */ + Word16 * cand1, /* (o) : index of best 1st stage vector */ + Word16 * cand2, /* (o) : index of best 2nd stage vector */ + Word16 gcode0 /* (i) Q4 : presearch for gain codebook */ + ) +{ + Word16 acc_h; + Word16 sft_x, sft_y; + Word32 L_acc, L_preg, L_cfbg, L_tmp, L_tmp_x, L_tmp_y; + Word32 L_temp; + + /*--------------------------------------------------------------------------* + x = (best_gain[1]-(coef[0][0]*best_gain[0]+coef[1][1])*gcode0) * inv_coef; + *--------------------------------------------------------------------------*/ + L_cfbg = L_mult (coef[0][0], best_gain[0]); /* L_cfbg:Q20 -> !!y */ + L_acc = L_shr (L_coef[1][1], 15); /* L_acc:Q20 */ + L_acc = L_add (L_cfbg, L_acc); + acc_h = extract_h (L_acc); /* acc_h:Q4 */ + L_preg = L_mult (acc_h, gcode0); /* L_preg:Q9 */ + L_acc = L_shl (L_deposit_l (best_gain[1]), 7); /* L_acc:Q9 */ + L_acc = L_sub (L_acc, L_preg); + acc_h = extract_h (L_shl (L_acc, 2)); /* L_acc_h:Q[-5] */ + L_tmp_x = L_mult (acc_h, INV_COEF); /* L_tmp_x:Q15 */ + + /*--------------------------------------------------------------------------* + y = (coef[1][0]*(-coef[0][1]+best_gain[0]*coef[0][0])*gcode0 + -coef[0][0]*best_gain[1]) * inv_coef; + *--------------------------------------------------------------------------*/ + L_acc = L_shr (L_coef[0][1], 10); /* L_acc:Q20 */ + L_acc = L_sub (L_cfbg, L_acc); /* !!x -> L_cfbg:Q20 */ + acc_h = extract_h (L_acc); /* acc_h:Q4 */ + acc_h = mult (acc_h, gcode0); /* acc_h:Q[-7] */ + L_tmp = L_mult (acc_h, coef[1][0]); /* L_tmp:Q10 */ + + L_preg = L_mult (coef[0][0], best_gain[1]); /* L_preg:Q13 */ + L_acc = L_sub (L_tmp, L_shr (L_preg, 3)); /* L_acc:Q10 */ + + acc_h = extract_h (L_shl (L_acc, 2)); /* acc_h:Q[-4] */ + L_tmp_y = L_mult (acc_h, INV_COEF); /* L_tmp_y:Q16 */ + + sft_y = (14 + 4 + 1) - 16; /* (Q[thr1]+Q[gcode0]+1)-Q[L_tmp_y] */ + sft_x = (15 + 4 + 1) - 15; /* (Q[thr2]+Q[gcode0]+1)-Q[L_tmp_x] */ + + if (gcode0 > 0) { + /*-- pre select codebook #1 --*/ + *cand1 = 0; + do { + L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y)); + if (L_temp > 0L) { + (*cand1) = add (*cand1, 1); + } + else + break; + } while (sub ((*cand1), (NCODE1 - NCAN1)) < 0); + /*-- pre select codebook #2 --*/ + *cand2 = 0; + do { + L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x)); + if (L_temp > 0L) { + (*cand2) = add (*cand2, 1); + } + else + break; + } while (sub ((*cand2), (NCODE2 - NCAN2)) < 0); + } + else { + /*-- pre select codebook #1 --*/ + *cand1 = 0; + do { + L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y)); + if (L_temp < 0L) { + (*cand1) = add (*cand1, 1); + } + else + break; + } while (sub ((*cand1), (NCODE1 - NCAN1))); + /*-- pre select codebook #2 --*/ + *cand2 = 0; + do { + L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x)); + if (L_temp < 0L) { + (*cand2) = add (*cand2, 1); + } + else + break; + } while (sub ((*cand2), (NCODE2 - NCAN2))); + } + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/qua_gain.h asterisk-1.2.1/codecs/g729a_v11/qua_gain.h --- asterisk-1.2.1.ori/codecs/g729a_v11/qua_gain.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/qua_gain.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,23 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*--------------------------------------------------------------------------* + * gain VQ functions. * + *--------------------------------------------------------------------------*/ + +Word16 Qua_gain (CodState *coder, + Word16 code[], /* (i) Q13 : Innovative vector. */ + Word16 g_coeff[], /* (i) : Correlations -2 */ + /* , -2, 2 */ + Word16 exp_coeff[], /* (i) : Q-Format g_coeff[] */ + Word16 L_subfr, /* (i) : Subframe length. */ + Word16 * gain_pit, /* (o) Q14 : Pitch gain. */ + Word16 * gain_cod, /* (o) Q1 : Code gain. */ + Word16 tameflag /* (i) : flag set to 1 if taming is needed */ + ); diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/qua_lsp.c asterisk-1.2.1/codecs/g729a_v11/qua_lsp.c --- asterisk-1.2.1.ori/codecs/g729a_v11/qua_lsp.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/qua_lsp.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,347 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------------* + * Function Qua_lsp: * + * ~~~~~~~~ * + *-------------------------------------------------------------------*/ +#include "typedef.h" +#include "basic_op.h" + +#include "ld8a.h" +#include "tab_ld8a.h" +#include "util.h" +#include "qua_lsp.h" +#include "lspgetq.h" +#include "lpcfunc.h" + +void +Qua_lsp (CodState *coder, + Word16 lsp[], /* (i) Q15 : Unquantized LSP */ + Word16 lsp_q[], /* (o) Q15 : Quantized LSP */ + Word16 ana[] /* (o) : indexes */ + ) +{ + Word16 lsf[M], lsf_q[M]; /* domain 0.0<= lsf freq_prev[i][0], M); +} + + +void +Lsp_qua_cs (CodState *coder, + Word16 flsp_in[M], /* (i) Q13 : Original LSP parameters */ + Word16 lspq_out[M], /* (o) Q13 : Quantized LSP parameters */ + Word16 * code /* (o) : codes of the selected LSP */ + ) +{ + Word16 wegt[M]; /* Q11->normalized : weighting coefficients */ + + Get_wegt (flsp_in, wegt); + + Relspwed (flsp_in, wegt, lspq_out, lspcb1, lspcb2, fg, + coder->freq_prev, fg_sum, fg_sum_inv, code); +} + +void +Relspwed (Word16 lsp[], /* (i) Q13 : unquantized LSP parameters */ + Word16 wegt[], /* (i) norm: weighting coefficients */ + Word16 lspq[], /* (o) Q13 : quantized LSP parameters */ + Word16 lspcb1[][M], /* (i) Q13 : first stage LSP codebook */ + Word16 lspcb2[][M], /* (i) Q13 : Second stage LSP codebook */ + Word16 fg[MODE][MA_NP][M], /* (i) Q15 : MA prediction coefficients */ + Word16 freq_prev[MA_NP][M], /* (i) Q13 : previous LSP vector */ + Word16 fg_sum[MODE][M], /* (i) Q15 : present MA prediction coef. */ + Word16 fg_sum_inv[MODE][M], /* (i) Q12 : inverse coef. */ + Word16 code_ana[] /* (o) : codes of the selected LSP */ + ) +{ + Word16 mode, j; + Word16 index, mode_index; + Word16 cand[MODE], cand_cur; + Word16 tindex1[MODE], tindex2[MODE]; + Word32 L_tdist[MODE]; /* Q26 */ + Word16 rbuf[M]; /* Q13 */ + Word16 buf[M]; /* Q13 */ + + for (mode = 0; mode < MODE; mode++) { + Lsp_prev_extract (lsp, rbuf, fg[mode], freq_prev, fg_sum_inv[mode]); + + Lsp_pre_select (rbuf, lspcb1, &cand_cur); + cand[mode] = cand_cur; + + Lsp_select_1 (rbuf, lspcb1[cand_cur], wegt, lspcb2, &index); + + tindex1[mode] = index; + + for (j = 0; j < NC; j++) + buf[j] = add (lspcb1[cand_cur][j], lspcb2[index][j]); + + Lsp_expand_1 (buf, GAP1); + + Lsp_select_2 (rbuf, lspcb1[cand_cur], wegt, lspcb2, &index); + + tindex2[mode] = index; + + for (j = NC; j < M; j++) + buf[j] = add (lspcb1[cand_cur][j], lspcb2[index][j]); + + Lsp_expand_2 (buf, GAP1); + + Lsp_expand_1_2 (buf, GAP2); + + Lsp_get_tdist (wegt, buf, &L_tdist[mode], rbuf, fg_sum[mode]); + } + + Lsp_last_select (L_tdist, &mode_index); + + code_ana[0] = shl (mode_index, NC0_B) | cand[mode_index]; + code_ana[1] = shl (tindex1[mode_index], NC1_B) | tindex2[mode_index]; + + Lsp_get_quant (lspcb1, lspcb2, cand[mode_index], + tindex1[mode_index], tindex2[mode_index], + fg[mode_index], freq_prev, lspq, fg_sum[mode_index]); + + return; +} + + +void +Lsp_pre_select (Word16 rbuf[], /* (i) Q13 : target vetor */ + Word16 lspcb1[][M], /* (i) Q13 : first stage LSP codebook */ + Word16 * cand /* (o) : selected code */ + ) +{ + Word16 i, j; + Word16 tmp; /* Q13 */ + Word32 L_dmin; /* Q26 */ + Word32 L_tmp; /* Q26 */ + Word32 L_temp; + + /* avoid the worst case. (all over flow) */ + + *cand = 0; + L_dmin = MAX_32; + for (i = 0; i < NC0; i++) { + L_tmp = 0; + for (j = 0; j < M; j++) { + tmp = sub (rbuf[j], lspcb1[i][j]); + L_tmp = L_mac (L_tmp, tmp, tmp); + } + + L_temp = L_sub (L_tmp, L_dmin); + if (L_temp < 0L) { + L_dmin = L_tmp; + *cand = i; + } + } + return; +} + + + +void +Lsp_select_1 (Word16 rbuf[], /* (i) Q13 : target vector */ + Word16 lspcb1[], /* (i) Q13 : first stage lsp codebook */ + Word16 wegt[], /* (i) norm: weighting coefficients */ + Word16 lspcb2[][M], /* (i) Q13 : second stage lsp codebook */ + Word16 * index /* (o) : selected codebook index */ + ) +{ + Word16 j, k1; + Word16 buf[M]; /* Q13 */ + Word32 L_dist; /* Q26 */ + Word32 L_dmin; /* Q26 */ + Word16 tmp, tmp2; /* Q13 */ + Word32 L_temp; + + for (j = 0; j < NC; j++) + buf[j] = sub (rbuf[j], lspcb1[j]); + + /* avoid the worst case. (all over flow) */ + *index = 0; + L_dmin = MAX_32; + for (k1 = 0; k1 < NC1; k1++) { + L_dist = 0; + for (j = 0; j < NC; j++) { + tmp = sub (buf[j], lspcb2[k1][j]); + tmp2 = mult (wegt[j], tmp); + L_dist = L_mac (L_dist, tmp2, tmp); + } + + L_temp = L_sub (L_dist, L_dmin); + if (L_temp < 0L) { + L_dmin = L_dist; + *index = k1; + } + } + return; +} + + + +void +Lsp_select_2 (Word16 rbuf[], /* (i) Q13 : target vector */ + Word16 lspcb1[], /* (i) Q13 : first stage lsp codebook */ + Word16 wegt[], /* (i) norm: weighting coef. */ + Word16 lspcb2[][M], /* (i) Q13 : second stage lsp codebook */ + Word16 * index /* (o) : selected codebook index */ + ) +{ + Word16 j, k1; + Word16 buf[M]; /* Q13 */ + Word32 L_dist; /* Q26 */ + Word32 L_dmin; /* Q26 */ + Word16 tmp, tmp2; /* Q13 */ + Word32 L_temp; + + for (j = NC; j < M; j++) + buf[j] = sub (rbuf[j], lspcb1[j]); + + /* avoid the worst case. (all over flow) */ + *index = 0; + L_dmin = MAX_32; + for (k1 = 0; k1 < NC1; k1++) { + L_dist = 0; + for (j = NC; j < M; j++) { + tmp = sub (buf[j], lspcb2[k1][j]); + tmp2 = mult (wegt[j], tmp); + L_dist = L_mac (L_dist, tmp2, tmp); + } + + L_temp = L_sub (L_dist, L_dmin); + if (L_temp < 0L) { + L_dmin = L_dist; + *index = k1; + } + } + return; +} + + + +void +Lsp_get_tdist (Word16 wegt[], /* (i) norm: weight coef. */ + Word16 buf[], /* (i) Q13 : candidate LSP vector */ + Word32 * L_tdist, /* (o) Q27 : distortion */ + Word16 rbuf[], /* (i) Q13 : target vector */ + Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */ + ) +{ + Word16 j; + Word16 tmp, tmp2; /* Q13 */ + Word32 L_acc; /* Q25 */ + + *L_tdist = 0; + for (j = 0; j < M; j++) { + /* tmp = (buf - rbuf)*fg_sum */ + tmp = sub (buf[j], rbuf[j]); + tmp = mult (tmp, fg_sum[j]); + + /* *L_tdist += wegt * tmp * tmp */ + L_acc = L_mult (wegt[j], tmp); + tmp2 = extract_h (L_shl (L_acc, 4)); + *L_tdist = L_mac (*L_tdist, tmp2, tmp); + } + + return; +} + + + +void +Lsp_last_select (Word32 L_tdist[], /* (i) Q27 : distortion */ + Word16 * mode_index /* (o) : the selected mode */ + ) +{ + Word32 L_temp; + *mode_index = 0; + L_temp = L_sub (L_tdist[1], L_tdist[0]); + if (L_temp < 0L) { + *mode_index = 1; + } + return; +} + +void +Get_wegt (Word16 flsp[], /* (i) Q13 : M LSP parameters */ + Word16 wegt[] /* (o) Q11->norm : M weighting coefficients */ + ) +{ + Word16 i; + Word16 tmp; + Word32 L_acc; + Word16 sft; + Word16 buf[M]; /* in Q13 */ + + + buf[0] = sub (flsp[1], (PI04 + 8192)); /* 8192:1.0(Q13) */ + + for (i = 1; i < M - 1; i++) { + tmp = sub (flsp[i + 1], flsp[i - 1]); + buf[i] = sub (tmp, 8192); + } + + buf[M - 1] = sub ((PI92 - 8192), flsp[M - 2]); + + /* */ + for (i = 0; i < M; i++) { + if (buf[i] > 0) { + wegt[i] = 2048; /* 2048:1.0(Q11) */ + } + else { + L_acc = L_mult (buf[i], buf[i]); /* L_acc in Q27 */ + tmp = extract_h (L_shl (L_acc, 2)); /* tmp in Q13 */ + + L_acc = L_mult (tmp, CONST10); /* L_acc in Q25 */ + tmp = extract_h (L_shl (L_acc, 2)); /* tmp in Q11 */ + + wegt[i] = add (tmp, 2048); /* wegt in Q11 */ + } + } + + /* */ + L_acc = L_mult (wegt[4], CONST12); /* L_acc in Q26 */ + wegt[4] = extract_h (L_shl (L_acc, 1)); /* wegt in Q11 */ + + L_acc = L_mult (wegt[5], CONST12); /* L_acc in Q26 */ + wegt[5] = extract_h (L_shl (L_acc, 1)); /* wegt in Q11 */ + + /* wegt: Q11 -> normalized */ + tmp = 0; + for (i = 0; i < M; i++) { + if (sub (wegt[i], tmp) > 0) { + tmp = wegt[i]; + } + } + + sft = norm_s (tmp); + for (i = 0; i < M; i++) { + wegt[i] = shl (wegt[i], sft); /* wegt in Q(11+sft) */ + } + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/qua_lsp.h asterisk-1.2.1/codecs/g729a_v11/qua_lsp.h --- asterisk-1.2.1.ori/codecs/g729a_v11/qua_lsp.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/qua_lsp.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,67 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------* + * LSP VQ functions. * + *-------------------------------*/ + +void Lsp_qua_cs (CodState *coder, + Word16 flsp_in[M], /* Q13 */ + Word16 lspq_out[M], /* Q13 */ + Word16 * code); + +void Lsp_get_tdist (Word16 wegt[], /* normalized */ + Word16 buf[], /* Q13 */ + Word32 * L_tdist, /* Q27 */ + Word16 rbuf[], /* Q13 */ + Word16 fg_sum[] /* Q15 */ + ); + +void Lsp_last_select (Word32 L_tdist[], /* Q27 */ + Word16 * mode_index); + +void Lsp_pre_select (Word16 rbuf[], /* Q13 */ + Word16 lspcb1[][M], /* Q13 */ + Word16 * cand); + +void Lsp_select_1 (Word16 rbuf[], /* Q13 */ + Word16 lspcb1[], /* Q13 */ + Word16 wegt[], /* normalized */ + Word16 lspcb2[][M], /* Q13 */ + Word16 * index); + +void Lsp_select_2 (Word16 rbuf[], /* Q13 */ + Word16 lspcb1[], /* Q13 */ + Word16 wegt[], /* normalized */ + Word16 lspcb2[][M], /* Q13 */ + Word16 * index); + +void Relspwed (Word16 lsp[], /* Q13 */ + Word16 wegt[], /* normalized */ + Word16 lspq[], /* Q13 */ + Word16 lspcb1[][M], /* Q13 */ + Word16 lspcb2[][M], /* Q13 */ + Word16 fg[MODE][MA_NP][M], /* Q15 */ + Word16 freq_prev[MA_NP][M], /* Q13 */ + Word16 fg_sum[MODE][M], /* Q15 */ + Word16 fg_sum_inv[MODE][M], /* Q12 */ + Word16 code_ana[] + ); + +void Qua_lsp (CodState *coder, + Word16 lsp[], /* (i) Q15 : Unquantized LSP */ + Word16 lsp_q[], /* (o) Q15 : Quantized LSP */ + Word16 ana[] /* (o) : indexes */ + ); + +void Get_wegt (Word16 flsp[], /* Q13 */ + Word16 wegt[] /* Q11 -> normalized */ + ); + +void Lsp_encw_reset (CodState *coder); diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/tab_ld8a.c asterisk-1.2.1/codecs/g729a_v11/tab_ld8a.c --- asterisk-1.2.1.ori/codecs/g729a_v11/tab_ld8a.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/tab_ld8a.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,786 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + + +/* This file contains all the tables used by the G.729A codec */ + +#include "typedef.h" +#include "ld8a.h" +#include "tab_ld8a.h" + +/* Hamming_cos window for LPC analysis. */ +/* Create with function ham_cos(window,200,40) */ + +Word16 hamwindow[L_WINDOW] = { + 2621, 2623, 2629, 2638, 2651, 2668, 2689, 2713, 2741, 2772, + 2808, 2847, 2890, 2936, 2986, 3040, 3097, 3158, 3223, 3291, + 3363, 3438, 3517, 3599, 3685, 3774, 3867, 3963, 4063, 4166, + 4272, 4382, 4495, 4611, 4731, 4853, 4979, 5108, 5240, 5376, + 5514, 5655, 5800, 5947, 6097, 6250, 6406, 6565, 6726, 6890, + 7057, 7227, 7399, 7573, 7750, 7930, 8112, 8296, 8483, 8672, + 8863, 9057, 9252, 9450, 9650, 9852, 10055, 10261, 10468, 10677, + 10888, 11101, 11315, 11531, 11748, 11967, 12187, 12409, 12632, 12856, + 13082, 13308, 13536, 13764, 13994, 14225, 14456, 14688, 14921, 15155, + 15389, 15624, 15859, 16095, 16331, 16568, 16805, 17042, 17279, 17516, + 17754, 17991, 18228, 18465, 18702, 18939, 19175, 19411, 19647, 19882, + 20117, 20350, 20584, 20816, 21048, 21279, 21509, 21738, 21967, 22194, + 22420, 22644, 22868, 23090, 23311, 23531, 23749, 23965, 24181, 24394, + 24606, 24816, 25024, 25231, 25435, 25638, 25839, 26037, 26234, 26428, + 26621, 26811, 26999, 27184, 27368, 27548, 27727, 27903, 28076, 28247, + 28415, 28581, 28743, 28903, 29061, 29215, 29367, 29515, 29661, 29804, + 29944, 30081, 30214, 30345, 30472, 30597, 30718, 30836, 30950, 31062, + 31170, 31274, 31376, 31474, 31568, 31659, 31747, 31831, 31911, 31988, + 32062, 32132, 32198, 32261, 32320, 32376, 32428, 32476, 32521, 32561, + 32599, 32632, 32662, 32688, 32711, 32729, 32744, 32755, 32763, 32767, + 32767, 32741, 32665, 32537, 32359, 32129, 31850, 31521, 31143, 30716, + 30242, 29720, 29151, 28538, 27879, 27177, 26433, 25647, 24821, 23957, + 23055, 22117, 21145, 20139, 19102, 18036, 16941, 15820, 14674, 13505, + 12315, 11106, 9879, 8637, 7381, 6114, 4838, 3554, 2264, 971 +}; + + +/*-----------------------------------------------------* + | Table of lag_window for autocorrelation. | + | noise floor = 1.0001 = (0.9999 on r[1] ..r[10]) | + | Bandwidth expansion = 60 Hz | + | | + | Special double precision format. See "oper_32b.c" | + | | + | lag_wind[0] = 1.00000000 (not stored) | + | lag_wind[1] = 0.99879038 | + | lag_wind[2] = 0.99546897 | + | lag_wind[3] = 0.98995781 | + | lag_wind[4] = 0.98229337 | + | lag_wind[5] = 0.97252619 | + | lag_wind[6] = 0.96072036 | + | lag_wind[7] = 0.94695264 | + | lag_wind[8] = 0.93131179 | + | lag_wind[9] = 0.91389757 | + | lag_wind[10]= 0.89481968 | + -----------------------------------------------------*/ + +Word16 lag_h[M] = { + 32728, + 32619, + 32438, + 32187, + 31867, + 31480, + 31029, + 30517, + 29946, + 29321 +}; + +Word16 lag_l[M] = { + 11904, + 17280, + 30720, + 25856, + 24192, + 28992, + 24384, + 7360, + 19520, + 14784 +}; + + +/*-----------------------------------------------------* + | Tables for function Lsf_lsp() and Lsp_lsf() | + -----------------------------------------------------*/ + +/* table of cos(x) in Q15 */ + +Word16 table[65] = { + 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, + 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, + 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010, + 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608, + 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039, + -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006, + -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622, + -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729, + -32768L +}; + +/* slope in Q12 used to compute y = acos(x) */ + +Word16 slope[64] = { + -26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811, + -1608, -1450, -1322, -1219, -1132, -1059, -998, -946, + -901, -861, -827, -797, -772, -750, -730, -713, + -699, -687, -677, -668, -662, -657, -654, -652, + -652, -654, -657, -662, -668, -677, -687, -699, + -713, -730, -750, -772, -797, -827, -861, -901, + -946, -998, -1059, -1132, -1219, -1322, -1450, -1608, + -1811, -2081, -2444, -2979, -3813, -5323, -8812, -26887 +}; + + +/*-----------------------------------------------------* + | Tables for function Lsf_lsp() and Lsp_lsf() | + -----------------------------------------------------*/ + +/* table of cos(x) in Q15 */ + +Word16 table2[64] = { + 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, + 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, + 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010, + 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608, + 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039, + -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006, + -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622, + -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729 +}; + +/* slope in Q19 used to compute y = cos(x) */ + +Word16 slope_cos[64] = { + -632, -1893, -3150, -4399, -5638, -6863, -8072, -9261, + -10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744, + -18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526, + -24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726, + -25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009, + -23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637, + -17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428, + -9261, -8072, -6863, -5638, -4399, -3150, -1893, -632 +}; + +/* slope in Q12 used to compute y = acos(x) */ + +Word16 slope_acos[64] = { + -26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811, + -1608, -1450, -1322, -1219, -1132, -1059, -998, -946, + -901, -861, -827, -797, -772, -750, -730, -713, + -699, -687, -677, -668, -662, -657, -654, -652, + -652, -654, -657, -662, -668, -677, -687, -699, + -713, -730, -750, -772, -797, -827, -861, -901, + -946, -998, -1059, -1132, -1219, -1322, -1450, -1608, + -1811, -2081, -2444, -2979, -3813, -5323, -8812, -26887 +}; + +/* lsp code book <../f7s55m1.v2> */ + +Word16 lspcb1[NC0][M] = { /* Q13 */ + {1486, 2168, 3751, 9074, 12134, 13944, 17983, 19173, 21190, 21820} + , + {1730, 2640, 3450, 4870, 6126, 7876, 15644, 17817, 20294, 21902} + , + {1568, 2256, 3088, 4874, 11063, 13393, 18307, 19293, 21109, 21741} + , + {1733, 2512, 3357, 4708, 6977, 10296, 17024, 17956, 19145, 20350} + , + {1744, 2436, 3308, 8731, 10432, 12007, 15614, 16639, 21359, 21913} + , + {1786, 2369, 3372, 4521, 6795, 12963, 17674, 18988, 20855, 21640} + , + {1631, 2433, 3361, 6328, 10709, 12013, 13277, 13904, 19441, 21088} + , + {1489, 2364, 3291, 6250, 9227, 10403, 13843, 15278, 17721, 21451} + , + {1869, 2533, 3475, 4365, 9152, 14513, 15908, 17022, 20611, 21411} + , + {2070, 3025, 4333, 5854, 7805, 9231, 10597, 16047, 20109, 21834} + , + {1910, 2673, 3419, 4261, 11168, 15111, 16577, 17591, 19310, 20265} + , + {1141, 1815, 2624, 4623, 6495, 9588, 13968, 16428, 19351, 21286} + , + {2192, 3171, 4707, 5808, 10904, 12500, 14162, 15664, 21124, 21789} + , + {1286, 1907, 2548, 3453, 9574, 11964, 15978, 17344, 19691, 22495} + , + {1921, 2720, 4604, 6684, 11503, 12992, 14350, 15262, 16997, 20791} + , + {2052, 2759, 3897, 5246, 6638, 10267, 15834, 16814, 18149, 21675} + , + {1798, 2497, 5617, 11449, 13189, 14711, 17050, 18195, 20307, 21182} + , + {1009, 1647, 2889, 5709, 9541, 12354, 15231, 18494, 20966, 22033} + , + {3016, 3794, 5406, 7469, 12488, 13984, 15328, 16334, 19952, 20791} + , + {2203, 3040, 3796, 5442, 11987, 13512, 14931, 16370, 17856, 18803} + , + {2912, 4292, 7988, 9572, 11562, 13244, 14556, 16529, 20004, 21073} + , + {2861, 3607, 5923, 7034, 9234, 12054, 13729, 18056, 20262, 20974} + , + {3069, 4311, 5967, 7367, 11482, 12699, 14309, 16233, 18333, 19172} + , + {2434, 3661, 4866, 5798, 10383, 11722, 13049, 15668, 18862, 19831} + , + {2020, 2605, 3860, 9241, 13275, 14644, 16010, 17099, 19268, 20251} + , + {1877, 2809, 3590, 4707, 11056, 12441, 15622, 17168, 18761, 19907} + , + {2107, 2873, 3673, 5799, 13579, 14687, 15938, 17077, 18890, 19831} + , + {1612, 2284, 2944, 3572, 8219, 13959, 15924, 17239, 18592, 20117} + , + {2420, 3156, 6542, 10215, 12061, 13534, 15305, 16452, 18717, 19880} + , + {1667, 2612, 3534, 5237, 10513, 11696, 12940, 16798, 18058, 19378} + , + {2388, 3017, 4839, 9333, 11413, 12730, 15024, 16248, 17449, 18677} + , + {1875, 2786, 4231, 6320, 8694, 10149, 11785, 17013, 18608, 19960} + , + {679, 1411, 4654, 8006, 11446, 13249, 15763, 18127, 20361, 21567} + , + {1838, 2596, 3578, 4608, 5650, 11274, 14355, 15886, 20579, 21754} + , + {1303, 1955, 2395, 3322, 12023, 13764, 15883, 18077, 20180, 21232} + , + {1438, 2102, 2663, 3462, 8328, 10362, 13763, 17248, 19732, 22344} + , + {860, 1904, 6098, 7775, 9815, 12007, 14821, 16709, 19787, 21132} + , + {1673, 2723, 3704, 6125, 7668, 9447, 13683, 14443, 20538, 21731} + , + {1246, 1849, 2902, 4508, 7221, 12710, 14835, 16314, 19335, 22720} + , + {1525, 2260, 3862, 5659, 7342, 11748, 13370, 14442, 18044, 21334} + , + {1196, 1846, 3104, 7063, 10972, 12905, 14814, 17037, 19922, 22636} + , + {2147, 3106, 4475, 6511, 8227, 9765, 10984, 12161, 18971, 21300} + , + {1585, 2405, 2994, 4036, 11481, 13177, 14519, 15431, 19967, 21275} + , + {1778, 2688, 3614, 4680, 9465, 11064, 12473, 16320, 19742, 20800} + , + {1862, 2586, 3492, 6719, 11708, 13012, 14364, 16128, 19610, 20425} + , + {1395, 2156, 2669, 3386, 10607, 12125, 13614, 16705, 18976, 21367} + , + {1444, 2117, 3286, 6233, 9423, 12981, 14998, 15853, 17188, 21857} + , + {2004, 2895, 3783, 4897, 6168, 7297, 12609, 16445, 19297, 21465} + , + {1495, 2863, 6360, 8100, 11399, 14271, 15902, 17711, 20479, 22061} + , + {2484, 3114, 5718, 7097, 8400, 12616, 14073, 14847, 20535, 21396} + , + {2424, 3277, 5296, 6284, 11290, 12903, 16022, 17508, 19333, 20283} + , + {2565, 3778, 5360, 6989, 8782, 10428, 14390, 15742, 17770, 21734} + , + {2727, 3384, 6613, 9254, 10542, 12236, 14651, 15687, 20074, 21102} + , + {1916, 2953, 6274, 8088, 9710, 10925, 12392, 16434, 20010, 21183} + , + {3384, 4366, 5349, 7667, 11180, 12605, 13921, 15324, 19901, 20754} + , + {3075, 4283, 5951, 7619, 9604, 11010, 12384, 14006, 20658, 21497} + , + {1751, 2455, 5147, 9966, 11621, 13176, 14739, 16470, 20788, 21756} + , + {1442, 2188, 3330, 6813, 8929, 12135, 14476, 15306, 19635, 20544} + , + {2294, 2895, 4070, 8035, 12233, 13416, 14762, 17367, 18952, 19688} + , + {1937, 2659, 4602, 6697, 9071, 12863, 14197, 15230, 16047, 18877} + , + {2071, 2663, 4216, 9445, 10887, 12292, 13949, 14909, 19236, 20341} + , + {1740, 2491, 3488, 8138, 9656, 11153, 13206, 14688, 20896, 21907} + , + {2199, 2881, 4675, 8527, 10051, 11408, 14435, 15463, 17190, 20597} + , + {1943, 2988, 4177, 6039, 7478, 8536, 14181, 15551, 17622, 21579} + , + {1825, 3175, 7062, 9818, 12824, 15450, 18330, 19856, 21830, 22412} + , + {2464, 3046, 4822, 5977, 7696, 15398, 16730, 17646, 20588, 21320} + , + {2550, 3393, 5305, 6920, 10235, 14083, 18143, 19195, 20681, 21336} + , + {3003, 3799, 5321, 6437, 7919, 11643, 15810, 16846, 18119, 18980} + , + {3455, 4157, 6838, 8199, 9877, 12314, 15905, 16826, 19949, 20892} + , + {3052, 3769, 4891, 5810, 6977, 10126, 14788, 15990, 19773, 20904} + , + {3671, 4356, 5827, 6997, 8460, 12084, 14154, 14939, 19247, 20423} + , + {2716, 3684, 5246, 6686, 8463, 10001, 12394, 14131, 16150, 19776} + , + {1945, 2638, 4130, 7995, 14338, 15576, 17057, 18206, 20225, 20997} + , + {2304, 2928, 4122, 4824, 5640, 13139, 15825, 16938, 20108, 21054} + , + {1800, 2516, 3350, 5219, 13406, 15948, 17618, 18540, 20531, 21252} + , + {1436, 2224, 2753, 4546, 9657, 11245, 15177, 16317, 17489, 19135} + , + {2319, 2899, 4980, 6936, 8404, 13489, 15554, 16281, 20270, 20911} + , + {2187, 2919, 4610, 5875, 7390, 12556, 14033, 16794, 20998, 21769} + , + {2235, 2923, 5121, 6259, 8099, 13589, 15340, 16340, 17927, 20159} + , + {1765, 2638, 3751, 5730, 7883, 10108, 13633, 15419, 16808, 18574} + , + {3460, 5741, 9596, 11742, 14413, 16080, 18173, 19090, 20845, 21601} + , + {3735, 4426, 6199, 7363, 9250, 14489, 16035, 17026, 19873, 20876} + , + {3521, 4778, 6887, 8680, 12717, 14322, 15950, 18050, 20166, 21145} + , + {2141, 2968, 6865, 8051, 10010, 13159, 14813, 15861, 17528, 18655} + , + {4148, 6128, 9028, 10871, 12686, 14005, 15976, 17208, 19587, 20595} + , + {4403, 5367, 6634, 8371, 10163, 11599, 14963, 16331, 17982, 18768} + , + {4091, 5386, 6852, 8770, 11563, 13290, 15728, 16930, 19056, 20102} + , + {2746, 3625, 5299, 7504, 10262, 11432, 13172, 15490, 16875, 17514} + , + {2248, 3556, 8539, 10590, 12665, 14696, 16515, 17824, 20268, 21247} + , + {1279, 1960, 3920, 7793, 10153, 14753, 16646, 18139, 20679, 21466} + , + {2440, 3475, 6737, 8654, 12190, 14588, 17119, 17925, 19110, 19979} + , + {1879, 2514, 4497, 7572, 10017, 14948, 16141, 16897, 18397, 19376} + , + {2804, 3688, 7490, 10086, 11218, 12711, 16307, 17470, 20077, 21126} + , + {2023, 2682, 3873, 8268, 10255, 11645, 15187, 17102, 18965, 19788} + , + {2823, 3605, 5815, 8595, 10085, 11469, 16568, 17462, 18754, 19876} + , + {2851, 3681, 5280, 7648, 9173, 10338, 14961, 16148, 17559, 18474} + , + {1348, 2645, 5826, 8785, 10620, 12831, 16255, 18319, 21133, 22586} + , + {2141, 3036, 4293, 6082, 7593, 10629, 17158, 18033, 21466, 22084} + , + {1608, 2375, 3384, 6878, 9970, 11227, 16928, 17650, 20185, 21120} + , + {2774, 3616, 5014, 6557, 7788, 8959, 17068, 18302, 19537, 20542} + , + {1934, 4813, 6204, 7212, 8979, 11665, 15989, 17811, 20426, 21703} + , + {2288, 3507, 5037, 6841, 8278, 9638, 15066, 16481, 21653, 22214} + , + {2951, 3771, 4878, 7578, 9016, 10298, 14490, 15242, 20223, 20990} + , + {3256, 4791, 6601, 7521, 8644, 9707, 13398, 16078, 19102, 20249} + , + {1827, 2614, 3486, 6039, 12149, 13823, 16191, 17282, 21423, 22041} + , + {1000, 1704, 3002, 6335, 8471, 10500, 14878, 16979, 20026, 22427} + , + {1646, 2286, 3109, 7245, 11493, 12791, 16824, 17667, 18981, 20222} + , + {1708, 2501, 3315, 6737, 8729, 9924, 16089, 17097, 18374, 19917} + , + {2623, 3510, 4478, 5645, 9862, 11115, 15219, 18067, 19583, 20382} + , + {2518, 3434, 4728, 6388, 8082, 9285, 13162, 18383, 19819, 20552} + , + {1726, 2383, 4090, 6303, 7805, 12845, 14612, 17608, 19269, 20181} + , + {2860, 3735, 4838, 6044, 7254, 8402, 14031, 16381, 18037, 19410} + , + {4247, 5993, 7952, 9792, 12342, 14653, 17527, 18774, 20831, 21699} + , + {3502, 4051, 5680, 6805, 8146, 11945, 16649, 17444, 20390, 21564} + , + {3151, 4893, 5899, 7198, 11418, 13073, 15124, 17673, 20520, 21861} + , + {3960, 4848, 5926, 7259, 8811, 10529, 15661, 16560, 18196, 20183} + , + {4499, 6604, 8036, 9251, 10804, 12627, 15880, 17512, 20020, 21046} + , + {4251, 5541, 6654, 8318, 9900, 11686, 15100, 17093, 20572, 21687} + , + {3769, 5327, 7865, 9360, 10684, 11818, 13660, 15366, 18733, 19882} + , + {3083, 3969, 6248, 8121, 9798, 10994, 12393, 13686, 17888, 19105} + , + {2731, 4670, 7063, 9201, 11346, 13735, 16875, 18797, 20787, 22360} + , + {1187, 2227, 4737, 7214, 9622, 12633, 15404, 17968, 20262, 23533} + , + {1911, 2477, 3915, 10098, 11616, 12955, 16223, 17138, 19270, 20729} + , + {1764, 2519, 3887, 6944, 9150, 12590, 16258, 16984, 17924, 18435} + , + {1400, 3674, 7131, 8718, 10688, 12508, 15708, 17711, 19720, 21068} + , + {2322, 3073, 4287, 8108, 9407, 10628, 15862, 16693, 19714, 21474} + , + {2630, 3339, 4758, 8360, 10274, 11333, 12880, 17374, 19221, 19936} + , + {1721, 2577, 5553, 7195, 8651, 10686, 15069, 16953, 18703, 19929} +}; + + +Word16 lspcb2[NC1][M] = { /* Q13 */ + {-435, -815, -742, 1033, -518, 582, -1201, 829, 86, 385} + , + {-833, -891, 463, -8, -1251, 1450, 72, -231, 864, 661} + , + {-1021, 231, -306, 321, -220, -163, -526, -754, -1633, 267} + , + {57, -198, -339, -33, -1468, 573, 796, -169, -631, 816} + , + {171, -350, 294, 1660, 453, 519, 291, 159, -640, -1296} + , + {-701, -842, -58, 950, 892, 1549, 715, 527, -714, -193} + , + {584, 31, -289, 356, -333, -457, 612, -283, -1381, -741} + , + {-109, -808, 231, 77, -87, -344, 1341, 1087, -654, -569} + , + {-859, 1236, 550, 854, 714, -543, -1752, -195, -98, -276} + , + {-877, -954, -1248, -299, 212, -235, -728, 949, 1517, 895} + , + {-77, 344, -620, 763, 413, 502, -362, -960, -483, 1386} + , + {-314, -307, -256, -1260, -429, 450, -466, -108, 1010, 2223} + , + {711, 693, 521, 650, 1305, -28, -378, 744, -1005, 240} + , + {-112, -271, -500, 946, 1733, 271, -15, 909, -259, 1688} + , + {575, -10, -468, -199, 1101, -1011, 581, -53, -747, 878} + , + {145, -285, -1280, -398, 36, -498, -1377, 18, -444, 1483} + , + {-1133, -835, 1350, 1284, -95, 1015, -222, 443, 372, -354} + , + {-1459, -1237, 416, -213, 466, 669, 659, 1640, 932, 534} + , + {-15, 66, 468, 1019, -748, 1385, -182, -907, -721, -262} + , + {-338, 148, 1445, 75, -760, 569, 1247, 337, 416, -121} + , + {389, 239, 1568, 981, 113, 369, -1003, -507, -587, -904} + , + {-312, -98, 949, 31, 1104, 72, -141, 1465, 63, -785} + , + {1127, 584, 835, 277, -1159, 208, 301, -882, 117, -404} + , + {539, -114, 856, -493, 223, -912, 623, -76, 276, -440} + , + {2197, 2337, 1268, 670, 304, -267, -525, 140, 882, -139} + , + {-1596, 550, 801, -456, -56, -697, 865, 1060, 413, 446} + , + {1154, 593, -77, 1237, -31, 581, -1037, -895, 669, 297} + , + {397, 558, 203, -797, -919, 3, 692, -292, 1050, 782} + , + {334, 1475, 632, -80, 48, -1061, -484, 362, -597, -852} + , + {-545, -330, -429, -680, 1133, -1182, -744, 1340, 262, 63} + , + {1320, 827, -398, -576, 341, -774, -483, -1247, -70, 98} + , + {-163, 674, -11, -886, 531, -1125, -265, -242, 724, 934} +}; +Word16 fg[2][MA_NP][M] = { /* Q15 */ + { + {8421, 9109, 9175, 8965, 9034, 9057, 8765, 8775, 9106, 8673} + , + {7018, 7189, 7638, 7307, 7444, 7379, 7038, 6956, 6930, 6868} + , + {5472, 4990, 5134, 5177, 5246, 5141, 5206, 5095, 4830, 5147} + , + {4056, 3031, 2614, 3024, 2916, 2713, 3309, 3237, 2857, 3473} + } + , + { + {7733, 7880, 8188, 8175, 8247, 8490, 8637, 8601, 8359, 7569} + , + {4210, 3031, 2552, 3473, 3876, 3853, 4184, 4154, 3909, 3968} + , + {3214, 1930, 1313, 2143, 2493, 2385, 2755, 2706, 2542, 2919} + , + {3024, 1592, 940, 1631, 1723, 1579, 2034, 2084, 1913, 2601} + } +}; +Word16 fg_sum[2][M] = { /* Q15 */ + {7798, 8447, 8205, 8293, 8126, 8477, 8447, 8703, 9043, 8604} + , + {14585, 18333, 19772, 17344, 16426, 16459, 15155, 15220, 16043, 15708} +}; +Word16 fg_sum_inv[2][M] = { /* Q12 */ + {17210, 15888, 16357, 16183, 16516, 15833, 15888, 15421, 14840, 15597} + , + {9202, 7320, 6788, 7738, 8170, 8154, 8856, 8818, 8366, 8544} +}; + +/*-------------------------------------------------------------* + * Table for az_lsf() * + * * + * Vector grid[] is in Q15 * + * * + * grid[0] = 1.0; * + * grid[grid_points+1] = -1.0; * + * for (i = 1; i < grid_points; i++) * + * grid[i] = cos((6.283185307*i)/(2.0*grid_points)); * + * * + *-------------------------------------------------------------*/ + +/* Version 51 points */ +Word16 grid[GRID_POINTS + 1] = { + 32760, 32703, 32509, 32187, 31738, 31164, + 30466, 29649, 28714, 27666, 26509, 25248, + 23886, 22431, 20887, 19260, 17557, 15786, + 13951, 12062, 10125, 8149, 6140, 4106, + 2057, 0, -2057, -4106, -6140, -8149, + -10125, -12062, -13951, -15786, -17557, -19260, + -20887, -22431, -23886, -25248, -26509, -27666, + -28714, -29649, -30466, -31164, -31738, -32187, + -32509, -32703, -32760 +}; + +/*-----------------------------------------------------* + | Tables for pitch related routines . | + -----------------------------------------------------*/ + +/* 1/3 resolution interpolation filter (-3 dB at 3600 Hz) in Q15 */ + +Word16 inter_3l[FIR_SIZE_SYN] = { + 29443, + 25207, 14701, 3143, + -4402, -5850, -2783, + 1211, 3130, 2259, + 0, -1652, -1666, + -464, 756, 1099, + 550, -245, -634, + -451, 0, 308, + 296, 78, -120, + -165, -79, 34, + 91, 70, 0 +}; + + /*Coefficients in floating point + + 0.898517, + 0.769271, 0.448635, 0.095915, + -0.134333, -0.178528, -0.084919, + 0.036952, 0.095533, 0.068936, + -0.000000, -0.050404, -0.050835, + -0.014169, 0.023083, 0.033543, + 0.016774, -0.007466, -0.019340, + -0.013755, 0.000000, 0.009400, + 0.009029, 0.002381, -0.003658, + -0.005027, -0.002405, 0.001050, + 0.002780, 0.002145, 0.000000}; + */ + +/*-----------------------------------------------------* + | Tables for gain related routines . | + -----------------------------------------------------*/ + +/* MA gain prediction coeff ={0.68, 0.58, 0.34, 0.19} in Q13 */ +Word16 pred[4] = { 5571, 4751, 2785, 1556 }; + + +Word16 gbk1[NCODE1][2] = { +/* Q14 Q13 */ + {1, 1516} + , + {1551, 2425} + , + {1831, 5022} + , + {57, 5404} + , + {1921, 9291} + , + {3242, 9949} + , + {356, 14756} + , + {2678, 27162} +}; + +Word16 gbk2[NCODE2][2] = { +/* Q14 Q13 */ + {826, 2005} + , + {1994, 0} + , + {5142, 592} + , + {6160, 2395} + , + {8091, 4861} + , + {9120, 525} + , + {10573, 2966} + , + {11569, 1196} + , + {13260, 3256} + , + {14194, 1630} + , + {15132, 4914} + , + {15161, 14276} + , + {15434, 237} + , + {16112, 3392} + , + {17299, 1861} + , + {18973, 5935} +}; + +Word16 map1[NCODE1] = { + 5, 1, 4, 7, 3, 0, 6, 2 +}; + +Word16 map2[NCODE2] = { + 4, 6, 0, 2, 12, 14, 8, 10, 15, 11, 9, 13, 7, 3, 1, 5 +}; + +/* [0][0] [0][1] [1][0] [1][1] */ +/* Q10 Q14 Q16 Q19 */ +Word16 coef[2][2] = { + {31881, 26416} + , + {31548, 27816} +}; + +/* [0][0] [0][1] [1][0] [1][1] */ +/* Q26 Q30 Q32 Q35 */ +Word32 L_coef[2][2] = { + {2089405952L, 1731217536L} + , + {2067549984L, 1822990272L} +}; + +Word16 thr1[NCODE1 - NCAN1] = { /* Q14 */ + 10808, + 12374, + 19778, + 32567 +}; +Word16 thr2[NCODE2 - NCAN2] = { /* Q15 */ + 14087, + 16188, + 20274, + 21321, + 23525, + 25232, + 27873, + 30542 +}; +Word16 imap1[NCODE1] = { + 5, 1, 7, 4, 2, 0, 6, 3 +}; + +Word16 imap2[NCODE2] = { + 2, 14, 3, 13, 0, 15, 1, 12, 6, 10, 7, 9, 4, 11, 5, 8 +}; + +/*-----------------------------------------------------* + | Tables for routines post_pro() & pre_proc(). | + -----------------------------------------------------*/ + +/* filter coefficients (fc = 100 Hz) */ + +Word16 b100[3] = { 7699, -15398, 7699 }; /* Q13 */ +Word16 a100[3] = { 8192, 15836, -7667 }; /* Q13 */ + +/* filter coefficients (fc = 140 Hz, coeff. b[] is divided by 2) */ + +Word16 b140[3] = { 1899, -3798, 1899 }; /* 1/2 in Q12 */ +Word16 a140[3] = { 4096, 7807, -3733 }; /* Q12 */ + +/*-----------------------------------------------------* + | Tables for routine bits(). | + -----------------------------------------------------*/ + + +Word16 bitsno[PRM_SIZE] = { 1 + NC0_B, /* MA + 1st stage */ + NC1_B * 2, /* 2nd stage */ + 8, 1, 13, 4, 7, /* first subframe */ + 5, 13, 4, 7 +}; /* second subframe */ + + +/*-----------------------------------------------------* + | Table for routine Pow2(). | + -----------------------------------------------------*/ + +Word16 tabpow[33] = { + 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911, + 20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726, + 25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706, + 31379, 32066, 32767 +}; + +/*-----------------------------------------------------* + | Table for routine Log2(). | + -----------------------------------------------------*/ + +Word16 tablog[33] = { + 0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, 10549, 11716, + 12855, 13967, 15054, 16117, 17156, 18172, 19167, 20142, 21097, 22033, + 22951, 23852, 24735, 25603, 26455, 27291, 28113, 28922, 29716, 30497, + 31266, 32023, 32767 +}; + +/*-----------------------------------------------------* + | Table for routine Inv_sqrt(). | + -----------------------------------------------------*/ + +Word16 tabsqr[49] = { + + 32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214, + 25705, 25225, 24770, 24339, 23930, 23541, 23170, 22817, 22479, 22155, + 21845, 21548, 21263, 20988, 20724, 20470, 20225, 19988, 19760, 19539, + 19326, 19119, 18919, 18725, 18536, 18354, 18176, 18004, 17837, 17674, + 17515, 17361, 17211, 17064, 16921, 16782, 16646, 16514, 16384 +}; + +/*-----------------------------------------------------* + | Table for taming procedure test_err. | + -----------------------------------------------------*/ + +Word16 tab_zone[PIT_MAX + L_INTERPOL - 1] = { + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 +}; + +Word16 lsp_old_init[M] = +{ + 30000, 26000, 21000, 15000, 8000, 0, -8000, -15000, -21000, -26000 +}; + +Word16 freq_prev_reset[M] = { /* Q13:previous LSP vector(init) */ + 2339, 4679, 7018, 9358, 11698, 14037, 16377, 18717, 21056, 23396 +}; /* PI*(float)(j+1)/(float)(M+1) */ + +Word16 past_qua_en_init [4] = { -14336, -14336, -14336, -14336 }; + + + diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/tab_ld8a.h asterisk-1.2.1/codecs/g729a_v11/tab_ld8a.h --- asterisk-1.2.1.ori/codecs/g729a_v11/tab_ld8a.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/tab_ld8a.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,48 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +extern Word16 hamwindow[L_WINDOW]; +extern Word16 lag_h[M]; +extern Word16 lag_l[M]; +extern Word16 table[65]; +extern Word16 slope[64]; +extern Word16 table2[64]; +extern Word16 slope_cos[64]; +extern Word16 slope_acos[64]; +extern Word16 lspcb1[NC0][M]; +extern Word16 lspcb2[NC1][M]; +extern Word16 fg[2][MA_NP][M]; +extern Word16 fg_sum[2][M]; +extern Word16 fg_sum_inv[2][M]; +extern Word16 grid[GRID_POINTS + 1]; +extern Word16 inter_3l[FIR_SIZE_SYN]; +extern Word16 pred[4]; +extern Word16 gbk1[NCODE1][2]; +extern Word16 gbk2[NCODE2][2]; +extern Word16 map1[NCODE1]; +extern Word16 map2[NCODE2]; +extern Word16 coef[2][2]; +extern Word32 L_coef[2][2]; +extern Word16 thr1[NCODE1 - NCAN1]; +extern Word16 thr2[NCODE2 - NCAN2]; +extern Word16 imap1[NCODE1]; +extern Word16 imap2[NCODE2]; +extern Word16 b100[3]; +extern Word16 a100[3]; +extern Word16 b140[3]; +extern Word16 a140[3]; +extern Word16 bitsno[PRM_SIZE]; +extern Word16 tabpow[33]; +extern Word16 tablog[33]; +extern Word16 tabsqr[49]; +extern Word16 tab_zone[PIT_MAX + L_INTERPOL - 1]; +extern Word16 lsp_old_init [M]; +extern Word16 freq_prev_reset[M]; +extern Word16 past_qua_en_init[4]; + diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/taming.c asterisk-1.2.1/codecs/g729a_v11/taming.c --- asterisk-1.2.1.ori/codecs/g729a_v11/taming.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/taming.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,139 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/************************************************************************** + * Taming functions. * + **************************************************************************/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "ld8a.h" +#include "tab_ld8a.h" +#include "taming.h" + +void +Init_exc_err (CodState *coder) +{ + Word16 i; + for (i = 0; i < 4; i++) + coder->L_exc_err[i] = 0x00004000L; /* Q14 */ +} + +/************************************************************************** + * routine test_err - computes the accumulated potential error in the * + * adaptive codebook contribution * + **************************************************************************/ + +Word16 +test_err (/* (o) flag set to 1 if taming is necessary */ + CodState *coder, + Word16 T0, /* (i) integer part of pitch delay */ + Word16 T0_frac /* (i) fractional part of pitch delay */ + ) +{ + Word16 i, t1, zone1, zone2, flag; + Word32 L_maxloc, L_acc; + + if (T0_frac > 0) { + t1 = add (T0, 1); + } + else { + t1 = T0; + } + + i = sub (t1, (L_SUBFR + L_INTER10)); + if (i < 0) { + i = 0; + } + zone1 = tab_zone[i]; + + i = add (t1, (L_INTER10 - 2)); + zone2 = tab_zone[i]; + + L_maxloc = -1L; + flag = 0; + for (i = zone2; i >= zone1; i--) { + L_acc = L_sub (coder->L_exc_err[i], L_maxloc); + if (L_acc > 0L) { + L_maxloc = coder->L_exc_err[i]; + } + } + L_acc = L_sub (L_maxloc, L_THRESH_ERR); + if (L_acc > 0L) { + flag = 1; + } + + return (flag); +} + +/************************************************************************** + *routine update_exc_err - maintains the memory used to compute the error * + * function due to an adaptive codebook mismatch between encoder and * + * decoder * + **************************************************************************/ + +void +update_exc_err (CodState *coder, + Word16 gain_pit, /* (i) pitch gain */ + Word16 T0 /* (i) integer part of pitch delay */ + ) +{ + + Word16 i, zone1, zone2, n; + Word32 L_worst, L_temp, L_acc; + Word16 hi, lo; + + L_worst = -1L; + n = sub (T0, L_SUBFR); + + if (n < 0) { + L_Extract (coder->L_exc_err[0], &hi, &lo); + L_temp = Mpy_32_16 (hi, lo, gain_pit); + L_temp = L_shl (L_temp, 1); + L_temp = L_add (0x00004000L, L_temp); + L_acc = L_sub (L_temp, L_worst); + if (L_acc > 0L) { + L_worst = L_temp; + } + L_Extract (L_temp, &hi, &lo); + L_temp = Mpy_32_16 (hi, lo, gain_pit); + L_temp = L_shl (L_temp, 1); + L_temp = L_add (0x00004000L, L_temp); + L_acc = L_sub (L_temp, L_worst); + if (L_acc > 0L) { + L_worst = L_temp; + } + } + + else { + + zone1 = tab_zone[n]; + + i = sub (T0, 1); + zone2 = tab_zone[i]; + + for (i = zone1; i <= zone2; i++) { + L_Extract (coder->L_exc_err[i], &hi, &lo); + L_temp = Mpy_32_16 (hi, lo, gain_pit); + L_temp = L_shl (L_temp, 1); + L_temp = L_add (0x00004000L, L_temp); + L_acc = L_sub (L_temp, L_worst); + if (L_acc > 0L) + L_worst = L_temp; + } + } + + for (i = 3; i >= 1; i--) { + coder->L_exc_err[i] = coder->L_exc_err[i - 1]; + } + coder->L_exc_err[0] = L_worst; + + return; +} diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/taming.h asterisk-1.2.1/codecs/g729a_v11/taming.h --- asterisk-1.2.1.ori/codecs/g729a_v11/taming.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/taming.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,22 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*--------------------------------------------------------------------------* + * Constants and prototypes for taming procedure. * + *--------------------------------------------------------------------------*/ + +#define GPCLIP 15564 /* Maximum pitch gain if taming is needed Q14 */ +#define GPCLIP2 481 /* Maximum pitch gain if taming is needed Q9 */ +#define GP0999 16383 /* Maximum pitch gain if taming is needed */ +#define L_THRESH_ERR 983040000L /* Error threshold taming 16384. * 60000. */ + +void Init_exc_err (CodState *coder); +void update_exc_err (CodState *coder, Word16 gain_pit, Word16 t0); +Word16 test_err (CodState *coder, Word16 t0, Word16 t0_frac); + diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/typedef.h asterisk-1.2.1/codecs/g729a_v11/typedef.h --- asterisk-1.2.1.ori/codecs/g729a_v11/typedef.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/typedef.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,16 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/* + Types definitions +*/ + +typedef short Word16; +typedef int Word32; +typedef int Flag; diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/util.c asterisk-1.2.1/codecs/g729a_v11/util.c --- asterisk-1.2.1.ori/codecs/g729a_v11/util.c 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/util.c 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,145 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*-------------------------------------------------------------------* + * Function Set zero() * + * ~~~~~~~~~~ * + * Set vector x[] to zero * + *-------------------------------------------------------------------*/ + +#include "typedef.h" +#include "basic_op.h" +#include "ld8a.h" +#include "tab_ld8a.h" + +void +Set_zero (Word16 x[], Word16 L) +{ + Word16 i; + + for (i = 0; i < L; i++) + x[i] = 0; + + return; +} + +/*-------------------------------------------------------------------* + * Function Copy: * + * ~~~~~ * + * Copy vector x[] to y[] * + *-------------------------------------------------------------------*/ + +void +Copy (Word16 x[], Word16 y[], Word16 L) +{ + Word16 i; + + for (i = 0; i < L; i++) + y[i] = x[i]; + + return; +} + +/* Random generator */ + +Word16 +Random (Word16* seed) +{ + /* seed = seed*31821 + 13849; */ + *seed = extract_l (L_add (L_shr (L_mult (*seed, 31821), 1), 13849L)); + + return (*seed); +} + + +/*---------------------------------------------------------------------------- + * Store_Param - converts encoder parameter vector into frame + * Restore_Params - converts serial received frame to encoder parameter vector + * + * The transmitted parameters are: + * + * LPC: 1st codebook 7+1 bit + * 2nd codebook 5+5 bit + * + * 1st subframe: + * pitch period 8 bit + * parity check on 1st period 1 bit + * codebook index1 (positions) 13 bit + * codebook index2 (signs) 4 bit + * pitch and codebook gains 4+3 bit + * + * 2nd subframe: + * pitch period (relative) 5 bit + * codebook index1 (positions) 13 bit + * codebook index2 (signs) 4 bit + * pitch and codebook gains 4+3 bit + *---------------------------------------------------------------------------- + */ + + +void +Store_Params(Word16 * parm, void *to) +{ + int i, j; + unsigned char mask, *to_b; + Word16 value, val_mask; + + to_b = (unsigned char *)to; + mask = 0x80; + for (i = 0; i < PRM_SIZE; i++) { + value = parm[i]; + val_mask = 1 << (bitsno[i] - 1); + for (j = 0; j < bitsno[i]; j++) { + + if (value & val_mask) + *to_b |= mask; + else + *to_b &= ~mask; + + value = value << 1; + mask = mask >> 1; + + if (mask == 0) { + mask = 0x80; + to_b++; + } + } + } + return; +} + +void Restore_Params(const void *from, Word16 * parm) +{ + int i, j; + unsigned char mask, *from_b; + Word16 value; + + mask = 0x80; + from_b = (unsigned char *)from; + + for (i = 0; i < PRM_SIZE; i++) { + value = 0; + for (j = 0; j < bitsno[i]; j++) { + + value = value << 1; + + if (mask & (*from_b)) + value += 1; + + mask = mask >> 1; + if (mask == 0) { + mask = 0x80; + from_b++; + } + } + parm[i] = value; + } + return; +} + diff -u -N -r asterisk-1.2.1.ori/codecs/g729a_v11/util.h asterisk-1.2.1/codecs/g729a_v11/util.h --- asterisk-1.2.1.ori/codecs/g729a_v11/util.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/g729a_v11/util.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,22 @@ +/* + ITU-T G.729A Speech Coder ANSI-C Source Code + Version 1.1 Last modified: September 1996 + + Copyright (c) 1996, + AT&T, France Telecom, NTT, Universite de Sherbrooke + All rights reserved. +*/ + +/*--------------------------------------------------------------------------* + * Prototypes for auxiliary functions. * + *--------------------------------------------------------------------------*/ + +void Copy (Word16 x[], Word16 y[], Word16 L); + +void Set_zero (Word16 x[], Word16 L); + +Word16 Random (Word16 *seed); + +void Store_Params(Word16 * parm, void *to); + +void Restore_Params(const void *from, Word16 * parm); diff -u -N -r asterisk-1.2.1.ori/codecs/slin_g729_ex.h asterisk-1.2.1/codecs/slin_g729_ex.h --- asterisk-1.2.1.ori/codecs/slin_g729_ex.h 1970-01-01 01:00:00.000000000 +0100 +++ asterisk-1.2.1/codecs/slin_g729_ex.h 2006-10-30 11:14:11.000000000 +0100 @@ -0,0 +1,30 @@ +/* + * Signed 16 bit audio data + * + */ +static signed short slin_g729_ex[] = { +0x0873, 0x06d9, 0x038c, 0x0588, 0x0409, 0x033d, 0x0311, 0xff6c, 0xfeef, 0xfd3e, +0xfdff, 0xff7a, 0xff6d, 0xffec, 0xff36, 0xfd62, 0xfda7, 0xfc6c, 0xfe67, 0xffe1, +0x003d, 0x01cc, 0x0065, 0x002a, 0xff83, 0xfed9, 0xffba, 0xfece, 0xff42, 0xff16, +0xfe85, 0xff31, 0xff02, 0xfdff, 0xfe32, 0xfe3f, 0xfed5, 0xff65, 0xffd4, 0x005b, +0xff88, 0xff01, 0xfebd, 0xfe95, 0xff46, 0xffe1, 0x00e2, 0x0165, 0x017e, 0x01c9, +0x0182, 0x0146, 0x00f9, 0x00ab, 0x006f, 0xffe8, 0xffd8, 0xffc4, 0xffb2, 0xfff9, +0xfffe, 0x0023, 0x0018, 0x000b, 0x001a, 0xfff7, 0x0014, 0x000b, 0x0004, 0x000b, +0xfff1, 0xff4f, 0xff3f, 0xff42, 0xff5e, 0xffd4, 0x0014, 0x0067, 0x0051, 0x003b, +0x0034, 0xfff9, 0x000d, 0xff54, 0xff54, 0xff52, 0xff3f, 0xffcc, 0xffe6, 0x00fc, +0x00fa, 0x00e4, 0x00f3, 0x0021, 0x0011, 0xffa1, 0xffab, 0xffdb, 0xffa5, 0x0009, +0xffd2, 0xffe6, 0x0007, 0x0096, 0x00e4, 0x00bf, 0x00ce, 0x0048, 0xffe8, 0xffab, +0xff8f, 0xffc3, 0xffc1, 0xfffc, 0x0002, 0xfff1, 0x000b, 0x00a7, 0x00c5, 0x00cc, +0x015e, 0x00e4, 0x0094, 0x0029, 0xffc7, 0xffc3, 0xff86, 0xffe4, 0xffe6, 0xffec, +0x000f, 0xffe3, 0x0028, 0x004b, 0xffaf, 0xffcb, 0xfedd, 0xfef8, 0xfe83, 0xfeba, +0xff94, 0xff94, 0xffbe, 0xffa8, 0xff0d, 0xff32, 0xff58, 0x0021, 0x0087, 0x00be, +0x0115, 0x007e, 0x0052, 0xfff0, 0xffc9, 0xffe8, 0xffc4, 0x0014, 0xfff0, 0xfff5, +0xfffe, 0xffda, 0x000b, 0x0010, 0x006f, 0x006f, 0x0052, 0x0045, 0xffee, 0xffea, +0xffcb, 0xffdf, 0xfffc, 0xfff0, 0x0012, 0xfff7, 0xfffe, 0x0018, 0x0050, 0x0066, +0x0047, 0x0028, 0xfff7, 0xffe8, 0xffec, 0x0007, 0x001d, 0x0016, 0x00c4, 0x0093, +0x007d, 0x0052, 0x00a5, 0x0091, 0x003c, 0x0041, 0xffd1, 0xffda, 0xffc6, 0xfff0, +0x001d, 0xfffe, 0x0024, 0xffee, 0xfff3, 0xfff0, 0xffea, 0x0012, 0xfff3, 0xfff7, +0xffda, 0xffca, 0xffda, 0xffdf, 0xfff3, 0xfff7, 0xff54, 0xff7c, 0xff8c, 0xffb9, +0x0012, 0x0012, 0x004c, 0x0007, 0xff50, 0xff66, 0xff54, 0xffa9, 0xffdc, 0xfff9, +0x0038, 0xfff9, 0x00d2, 0x0096, 0x008a, 0x0079, 0xfff5, 0x0019, 0xffad, 0xfffc }; +