From 89c5b2369413025e1fe7dfe5c5d0bf3bedd8558d Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Mon, 23 Jul 2012 13:52:57 +0000 Subject: git-svn-id: http://svn.miranda-ng.org/main/trunk@1123 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- !NotAdopted/Tlen/codec/gsm.h | 65 ++++++++ !NotAdopted/Tlen/codec/gsm_codec.c | 283 ++++++++++++++++++++++++++++++++ !NotAdopted/Tlen/codec/gsm_long.c | 183 +++++++++++++++++++++ !NotAdopted/Tlen/codec/gsm_lpc.c | 208 +++++++++++++++++++++++ !NotAdopted/Tlen/codec/gsm_preprocess.c | 103 ++++++++++++ !NotAdopted/Tlen/codec/gsm_rpe.c | 248 ++++++++++++++++++++++++++++ !NotAdopted/Tlen/codec/gsm_short.c | 211 ++++++++++++++++++++++++ 7 files changed, 1301 insertions(+) create mode 100644 !NotAdopted/Tlen/codec/gsm.h create mode 100644 !NotAdopted/Tlen/codec/gsm_codec.c create mode 100644 !NotAdopted/Tlen/codec/gsm_long.c create mode 100644 !NotAdopted/Tlen/codec/gsm_lpc.c create mode 100644 !NotAdopted/Tlen/codec/gsm_preprocess.c create mode 100644 !NotAdopted/Tlen/codec/gsm_rpe.c create mode 100644 !NotAdopted/Tlen/codec/gsm_short.c (limited to '!NotAdopted/Tlen/codec') diff --git a/!NotAdopted/Tlen/codec/gsm.h b/!NotAdopted/Tlen/codec/gsm.h new file mode 100644 index 0000000000..fba1bcb1ac --- /dev/null +++ b/!NotAdopted/Tlen/codec/gsm.h @@ -0,0 +1,65 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include + +#define P_MAX 8 /* order p of LPC analysis, typically 8..14 */ + +typedef struct { + int LARpp[2][8]; /* LAR coefficients for previous and current frame */ + int j; /* current frame index in LARpp[j][] */ + int qLARs[8]; /* quantized LARs for current frame */ + int u[8]; /* used by short term analysis filter */ + int v[9]; /* used by short term synthesis filter */ + int subframe; /* subframe index (0..3)*/ + short dp0[ 280 ]; /* previous short-term filter output/prediction, used by long term analysis*/ + int e[160]; /* errors (residuals) */ + int nrp; /* long term synthesis */ + int Nc[4], bc[4]; /* long-term lag and gain for current frame */ + int Mc[4]; /* RPE grid index (0..3) */ + int xMaxc[4]; /* RPE maximum error quantized and encoded (mantissa + exp) */ + int xMc[52]; /* quantized residuals (errors) 4 * 13 */ + + int z1; /* preprocessing.c, Offset_com. */ + int z2; /* Offset_com. */ + int mp; /* Preemphasis */ + int msr; /* decoder.c, Postprocessing */ + + unsigned char gsmFrame[33]; +}gsm_state; + +extern gsm_state * gsm_create() ; +extern void gsm_release(gsm_state *ptr); +extern void gsm_encode(gsm_state *state, short *in); +extern void gsm_decode(gsm_state *state, short *out); + +extern void gsm_preprocessing( gsm_state *state, short *in, short *out); +extern void shortTermAnalysis(gsm_state *state, short *in); +extern void longTermAnalysis(gsm_state *state, short *in); +extern void encodeRPE(gsm_state *state); +extern void decodeRPE(gsm_state *state); +extern void longTermSynthesis(gsm_state *state); +extern void shortTermSynthesis(gsm_state *state, short *in, short *out); +extern void gsm_postprocessing( gsm_state *state, short *in, short *out); diff --git a/!NotAdopted/Tlen/codec/gsm_codec.c b/!NotAdopted/Tlen/codec/gsm_codec.c new file mode 100644 index 0000000000..1d0a08a41e --- /dev/null +++ b/!NotAdopted/Tlen/codec/gsm_codec.c @@ -0,0 +1,283 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "gsm.h" +#include +#include +#include +#define GSM_MAGIC 0xD + +gsm_state * gsm_create() +{ + gsm_state * state = (gsm_state *)malloc(sizeof(gsm_state)); + memset(state, 0, sizeof(gsm_state)); + state->nrp = 40; + return state; +} + +void gsm_release(gsm_state *ptr) +{ + free(ptr); +} + +void gsm_encode(gsm_state *state, short *in) +{ int i, j; + unsigned char *c = state->gsmFrame; + short temp_in[160]; + + gsm_preprocessing(state, in, temp_in); + shortTermAnalysis(state, temp_in); + for (i = 0; i < 4; i++) { + state->subframe = i; + longTermAnalysis(state, temp_in + 40 * i); + encodeRPE(state); + for (j = 0; j < 40; j++) { + int ii = (int) state->dp0[120 + i * 40 + j] + state->e[i * 40 + j]; + if (ii<-32768) ii = -32768; + else if (ii>32767) ii=32767; + state->dp0[120 + i * 40 + j] = ii; + } + } + memcpy(state->dp0, state->dp0 + 160, 120 * sizeof(short)); + state->j ^= 1; + *c++ = ((GSM_MAGIC & 0xF) << 4) + | ((state->qLARs[0] >> 2) & 0xF); + *c++ = ((state->qLARs[0] & 0x3) << 6) + | (state->qLARs[1] & 0x3F); + *c++ = ((state->qLARs[2] & 0x1F) << 3) + | ((state->qLARs[3] >> 2) & 0x7); + *c++ = ((state->qLARs[3] & 0x3) << 6) + | ((state->qLARs[4] & 0xF) << 2) + | ((state->qLARs[5] >> 2) & 0x3); + *c++ = ((state->qLARs[5] & 0x3) << 6) + | ((state->qLARs[6] & 0x7) << 3) + | (state->qLARs[7] & 0x7); + *c++ = ((state->Nc[0] & 0x7F) << 1) + | ((state->bc[0] >> 1) & 0x1); + *c++ = ((state->bc[0] & 0x1) << 7) + | ((state->Mc[0] & 0x3) << 5) + | ((state->xMaxc[0] >> 1) & 0x1F); + *c++ = ((state->xMaxc[0] & 0x1) << 7) + | ((state->xMc[0] & 0x7) << 4) + | ((state->xMc[1] & 0x7) << 1) + | ((state->xMc[2] >> 2) & 0x1); + *c++ = ((state->xMc[2] & 0x3) << 6) + | ((state->xMc[3] & 0x7) << 3) + | (state->xMc[4] & 0x7); + *c++ = ((state->xMc[5] & 0x7) << 5) + | ((state->xMc[6] & 0x7) << 2) + | ((state->xMc[7] >> 1) & 0x3); + *c++ = ((state->xMc[7] & 0x1) << 7) + | ((state->xMc[8] & 0x7) << 4) + | ((state->xMc[9] & 0x7) << 1) + | ((state->xMc[10] >> 2) & 0x1); + *c++ = ((state->xMc[10] & 0x3) << 6) + | ((state->xMc[11] & 0x7) << 3) + | (state->xMc[12] & 0x7); + *c++ = ((state->Nc[1] & 0x7F) << 1) + | ((state->bc[1] >> 1) & 0x1); + *c++ = ((state->bc[1] & 0x1) << 7) + | ((state->Mc[1] & 0x3) << 5) + | ((state->xMaxc[1] >> 1) & 0x1F); + *c++ = ((state->xMaxc[1] & 0x1) << 7) + | ((state->xMc[13] & 0x7) << 4) + | ((state->xMc[14] & 0x7) << 1) + | ((state->xMc[15] >> 2) & 0x1); + *c++ = ((state->xMc[15] & 0x3) << 6) + | ((state->xMc[16] & 0x7) << 3) + | (state->xMc[17] & 0x7); + *c++ = ((state->xMc[18] & 0x7) << 5) + | ((state->xMc[19] & 0x7) << 2) + | ((state->xMc[20] >> 1) & 0x3); + *c++ = ((state->xMc[20] & 0x1) << 7) + | ((state->xMc[21] & 0x7) << 4) + | ((state->xMc[22] & 0x7) << 1) + | ((state->xMc[23] >> 2) & 0x1); + *c++ = ((state->xMc[23] & 0x3) << 6) + | ((state->xMc[24] & 0x7) << 3) + | (state->xMc[25] & 0x7); + *c++ = ((state->Nc[2] & 0x7F) << 1) + | ((state->bc[2] >> 1) & 0x1); + *c++ = ((state->bc[2] & 0x1) << 7) + | ((state->Mc[2] & 0x3) << 5) + | ((state->xMaxc[2] >> 1) & 0x1F); + *c++ = ((state->xMaxc[2] & 0x1) << 7) + | ((state->xMc[26] & 0x7) << 4) + | ((state->xMc[27] & 0x7) << 1) + | ((state->xMc[28] >> 2) & 0x1); + *c++ = ((state->xMc[28] & 0x3) << 6) + | ((state->xMc[29] & 0x7) << 3) + | (state->xMc[30] & 0x7); + *c++ = ((state->xMc[31] & 0x7) << 5) + | ((state->xMc[32] & 0x7) << 2) + | ((state->xMc[33] >> 1) & 0x3); + *c++ = ((state->xMc[33] & 0x1) << 7) + | ((state->xMc[34] & 0x7) << 4) + | ((state->xMc[35] & 0x7) << 1) + | ((state->xMc[36] >> 2) & 0x1); + *c++ = ((state->xMc[36] & 0x3) << 6) + | ((state->xMc[37] & 0x7) << 3) + | (state->xMc[38] & 0x7); + *c++ = ((state->Nc[3] & 0x7F) << 1) + | ((state->bc[3] >> 1) & 0x1); + *c++ = ((state->bc[3] & 0x1) << 7) + | ((state->Mc[3] & 0x3) << 5) + | ((state->xMaxc[3] >> 1) & 0x1F); + *c++ = ((state->xMaxc[3] & 0x1) << 7) + | ((state->xMc[39] & 0x7) << 4) + | ((state->xMc[40] & 0x7) << 1) + | ((state->xMc[41] >> 2) & 0x1); + *c++ = ((state->xMc[41] & 0x3) << 6) + | ((state->xMc[42] & 0x7) << 3) + | (state->xMc[43] & 0x7); + *c++ = ((state->xMc[44] & 0x7) << 5) + | ((state->xMc[45] & 0x7) << 2) + | ((state->xMc[46] >> 1) & 0x3); + *c++ = ((state->xMc[46] & 0x1) << 7) + | ((state->xMc[47] & 0x7) << 4) + | ((state->xMc[48] & 0x7) << 1) + | ((state->xMc[49] >> 2) & 0x1); + *c++ = ((state->xMc[49] & 0x3) << 6) + | ((state->xMc[50] & 0x7) << 3) + | (state->xMc[51] & 0x7); +} + +void gsm_decode(gsm_state *state, short *out) +{ + int i; + unsigned char *c = state->gsmFrame; + + if (((*c >> 4) & 0x0F) != GSM_MAGIC) return ; + state->qLARs[0] = (*c++ & 0xF) << 2; + state->qLARs[0] |= (*c >> 6) & 0x3; + state->qLARs[1] = *c++ & 0x3F; + state->qLARs[2] = (*c >> 3) & 0x1F; + state->qLARs[3] = (*c++ & 0x7) << 2; + state->qLARs[3] |= (*c >> 6) & 0x3; + state->qLARs[4] = (*c >> 2) & 0xF; + state->qLARs[5] = (*c++ & 0x3) << 2; + state->qLARs[5] |= (*c >> 6) & 0x3; + state->qLARs[6] = (*c >> 3) & 0x7; + state->qLARs[7] = *c++ & 0x7; + state->Nc[0] = (*c >> 1) & 0x7F; + state->bc[0] = (*c++ & 0x1) << 1; + state->bc[0] |= (*c >> 7) & 0x1; + state->Mc[0] = (*c >> 5) & 0x3; + state->xMaxc[0] = (*c++ & 0x1F) << 1; + state->xMaxc[0] |= (*c >> 7) & 0x1; + state->xMc[0] = (*c >> 4) & 0x7; + state->xMc[1] = (*c >> 1) & 0x7; + state->xMc[2] = (*c++ & 0x1) << 2; + state->xMc[2] |= (*c >> 6) & 0x3; + state->xMc[3] = (*c >> 3) & 0x7; + state->xMc[4] = *c++ & 0x7; + state->xMc[5] = (*c >> 5) & 0x7; + state->xMc[6] = (*c >> 2) & 0x7; + state->xMc[7] = (*c++ & 0x3) << 1; + state->xMc[7] |= (*c >> 7) & 0x1; + state->xMc[8] = (*c >> 4) & 0x7; + state->xMc[9] = (*c >> 1) & 0x7; + state->xMc[10] = (*c++ & 0x1) << 2; + state->xMc[10] |= (*c >> 6) & 0x3; + state->xMc[11] = (*c >> 3) & 0x7; + state->xMc[12] = *c++ & 0x7; + state->Nc[1] = (*c >> 1) & 0x7F; + state->bc[1] = (*c++ & 0x1) << 1; + state->bc[1] |= (*c >> 7) & 0x1; + state->Mc[1] = (*c >> 5) & 0x3; + state->xMaxc[1] = (*c++ & 0x1F) << 1; + state->xMaxc[1] |= (*c >> 7) & 0x1; + state->xMc[13] = (*c >> 4) & 0x7; + state->xMc[14] = (*c >> 1) & 0x7; + state->xMc[15] = (*c++ & 0x1) << 2; + state->xMc[15] |= (*c >> 6) & 0x3; + state->xMc[16] = (*c >> 3) & 0x7; + state->xMc[17] = *c++ & 0x7; + state->xMc[18] = (*c >> 5) & 0x7; + state->xMc[19] = (*c >> 2) & 0x7; + state->xMc[20] = (*c++ & 0x3) << 1; + state->xMc[20] |= (*c >> 7) & 0x1; + state->xMc[21] = (*c >> 4) & 0x7; + state->xMc[22] = (*c >> 1) & 0x7; + state->xMc[23] = (*c++ & 0x1) << 2; + state->xMc[23] |= (*c >> 6) & 0x3; + state->xMc[24] = (*c >> 3) & 0x7; + state->xMc[25] = *c++ & 0x7; + state->Nc[2] = (*c >> 1) & 0x7F; + state->bc[2] = (*c++ & 0x1) << 1; + state->bc[2] |= (*c >> 7) & 0x1; + state->Mc[2] = (*c >> 5) & 0x3; + state->xMaxc[2] = (*c++ & 0x1F) << 1; + state->xMaxc[2] |= (*c >> 7) & 0x1; + state->xMc[26] = (*c >> 4) & 0x7; + state->xMc[27] = (*c >> 1) & 0x7; + state->xMc[28] = (*c++ & 0x1) << 2; + state->xMc[28] |= (*c >> 6) & 0x3; + state->xMc[29] = (*c >> 3) & 0x7; + state->xMc[30] = *c++ & 0x7; + state->xMc[31] = (*c >> 5) & 0x7; + state->xMc[32] = (*c >> 2) & 0x7; + state->xMc[33] = (*c++ & 0x3) << 1; + state->xMc[33] |= (*c >> 7) & 0x1; + state->xMc[34] = (*c >> 4) & 0x7; + state->xMc[35] = (*c >> 1) & 0x7; + state->xMc[36] = (*c++ & 0x1) << 2; + state->xMc[36] |= (*c >> 6) & 0x3; + state->xMc[37] = (*c >> 3) & 0x7; + state->xMc[38] = *c++ & 0x7; + state->Nc[3] = (*c >> 1) & 0x7F; + state->bc[3] = (*c++ & 0x1) << 1; + state->bc[3] |= (*c >> 7) & 0x1; + state->Mc[3] = (*c >> 5) & 0x3; + state->xMaxc[3] = (*c++ & 0x1F) << 1; + state->xMaxc[3] |= (*c >> 7) & 0x1; + state->xMc[39] = (*c >> 4) & 0x7; + state->xMc[40] = (*c >> 1) & 0x7; + state->xMc[41] = (*c++ & 0x1) << 2; + state->xMc[41] |= (*c >> 6) & 0x3; + state->xMc[42] = (*c >> 3) & 0x7; + state->xMc[43] = *c++ & 0x7; + state->xMc[44] = (*c >> 5) & 0x7; + state->xMc[45] = (*c >> 2) & 0x7; + state->xMc[46] = (*c++ & 0x3) << 1; + state->xMc[46] |= (*c >> 7) & 0x1; + state->xMc[47] = (*c >> 4) & 0x7; + state->xMc[48] = (*c >> 1) & 0x7; + state->xMc[49] = (*c++ & 0x1) << 2; + state->xMc[49] |= (*c >> 6) & 0x3; + state->xMc[50] = (*c >> 3) & 0x7; + state->xMc[51] = *c & 0x7; + + for (i = 0; i < 4; i++) { + state->subframe = i; + decodeRPE(state); + longTermSynthesis(state); + } + memcpy(state->dp0, state->dp0 + 160, 120 * sizeof(short)); + shortTermSynthesis(state, &state->dp0[120], out); + gsm_postprocessing(state, out, out); + state->j ^= 1; +} diff --git a/!NotAdopted/Tlen/codec/gsm_long.c b/!NotAdopted/Tlen/codec/gsm_long.c new file mode 100644 index 0000000000..7d9148061c --- /dev/null +++ b/!NotAdopted/Tlen/codec/gsm_long.c @@ -0,0 +1,183 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "gsm.h" +#include +#include +#include + +/* Decision levels */ +const static int gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; +/* Quantization levels */ +const static int gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; + +/* + * Long term parameters calculation - lag (Nc) and gain (bc). + */ +static void longTermLTPCalculation(gsm_state *state, short *in, short *in_1) +{ + int k, lambda; + int Nc, bc; + float in_1_float_base[120], * in_1_float = in_1_float_base + 120; + float in_float[40]; + float L_result, L_max, L_power; + + for (k = -120; k < 0; k++) in_1_float[k] = (float)in_1[k]; + for (k = 0; k < 40; k++) in_float[k] = (float)in[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag */ + + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda < 121; lambda++) { + for (L_result = 0, L_power = 0, k = 0; k < 40; k++) { + L_result += in_float[k] * in_1_float[k - lambda]; +// L_power += in_1_float[k - lambda] * in_1_float[k - lambda]; + } +// L_result = L_result / L_power; + if (L_result > L_max) { + Nc = lambda; + L_max = L_result; + } + } + state->Nc[state->subframe] = Nc; + if (L_max <= 0.) { + state->bc[state->subframe] = 0; + return; + } + /* Compute the power of the reconstructed short term residual signal dp[..] */ + in_1_float -= Nc; + L_power = 0; + for (k = 0; k < 40; k++) { + float f = in_1_float[k]; + L_power += f * f; + } + if (L_max >= L_power) { //1.0 + state->bc[state->subframe] = 3; + return; + } + /* Coding of the LTP gain + * Table gsm_DLB must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ +// lambda = L_max * 32768.; + lambda = (int)(L_max * 32768. / L_power); + for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; + state->bc[state->subframe] = bc; +} + +/* + * Here we decode the bc parameter and compute samples of the estimate out[0..39]. + * The decoding of bc needs the gsm_QLB table. + * The long term residual signal e[0..39] is then calculated to be fed to the + * RPE encoding section. + */ +static void longTermAnalysisFilter(int Nc, int bc, short *in, short *in_1, short *out, int *e) +{ + int gain, k, l; + gain = gsm_QLB[bc]; + for (k = 0; k < 40; k++) { + l = (gain * (int)in_1[k - Nc] + 16384) >> 15; + if (l < -32768) l = -32768; + else if (l > 32767) l = 32767; + out[k] = l; + e[k] = in[k] - l; + } +} + +/* + * This procedure uses the bcr and Ncr parameter to realize the + * long term synthesis filtering. The decoding of bcr needs table gsm_QLB. + */ +static void longTermSynthesisFilter(gsm_state * state, int Ncr, int bcr, int *e, short *out) +{ + int k; + int brp, Nr; + + /* Check the limits of Nr. */ + Nr = Ncr < 40 || Ncr > 120 ? state->nrp : Ncr; + state->nrp = Nr; + /* Decoding of the LTP gain bcr */ + brp = gsm_QLB[ bcr ]; + + /* Computation of the reconstructed short term residual + * signal drp[0..39] + */ + for (k = 0; k < 40; k++) { + int temp = (brp * (int)out[ k-Nr ] + 16384) >> 15; + out[k] = e[k] + temp; + } +} + +/* + * This procedure performs long term analysis. + */ +void longTermAnalysis(gsm_state *state, short *in) +{ + short *in_1 = state->dp0 + 120 + state->subframe * 40; + short *out = state->dp0 + 120 + state->subframe * 40; + int *e = state->e + state->subframe * 40; +/* + + int i; + printf("Long-term in: \n"); + for (i=0;i<40;i++) { + printf("%7d ", in[i]); + } + printf("\n"); + */ + longTermLTPCalculation(state, in, in_1); + /* printf("Nc: %d, bc: %d \n", state->Nc[state->subframe], state->bc[state->subframe]); + */ + longTermAnalysisFilter(state->Nc[state->subframe], state->bc[state->subframe], in, in_1, out, e); +/* + printf("Long-term out: \n"); + for (i=0;i<40;i++) { + printf("%7d ", out[i]); + } + printf("\n"); + */ +} + +/* + * This procedure performs long term synthesis. + */ +void longTermSynthesis(gsm_state *state) +{ + int Nc = state->Nc[state->subframe]; + int bc = state->bc[state->subframe]; + int *e = state->e + state->subframe * 40; + short *out = state->dp0 + 120 + state->subframe * 40; + //int i; + longTermSynthesisFilter(state, Nc, bc, e, out); + /* + printf("Long-term reconstructed: \n"); + for (i=0;i<160;i++) { + printf("%7d ", state->dp0[i]); + } + printf("\n"); + */ +} diff --git a/!NotAdopted/Tlen/codec/gsm_lpc.c b/!NotAdopted/Tlen/codec/gsm_lpc.c new file mode 100644 index 0000000000..519612baff --- /dev/null +++ b/!NotAdopted/Tlen/codec/gsm_lpc.c @@ -0,0 +1,208 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/* LPC- and Reflection Coefficients + * The next two functions calculate linear prediction coefficients + * and/or the related reflection coefficients from the first P_MAX+1 + * values of the autocorrelation function. + */ +#include "gsm.h" /* for P_MAX */ +#include +#include +#include + +/* Compute the autocorrelation + * ,--, + * ac(l) = > x(i) * x(i-l) for all i + * `--' + * for lags l between 0 and lag-1, and x(i) == 0 for i < 0 or i >= n + * @param n: number of samples + * @param lax: max lag (order) + * @param in: [0...n-1] samples x + * @param out: [0...lag-1] autocorrelation + */ +static void autocorrelation(int n, float const *x, int lag, float *ac) +{ + float d; + int i, j; + for (j = 0; j < lag; j++) { + for (i = j, d = 0; i < n; i++) d += x[i] * x[i-j]; + ac[j] = d; + } + d = (float)fabs(ac[0]); + if (d != 0) { + for (j = 0; j < lag; j++) ac[j] /= d; + } +} + +/* The Levinson-Durbin algorithm was invented by N. Levinson in 1947 + * and modified by J. Durbin in 1959. + * @param in: [0...p] autocorrelation values + * @param out: [0...p-1] reflection coefficients + * @param lpc: [0...p-1] LPC coefficients + * @return minimum mean square error + */ +/* +static float levinson_durbin (float const *ac, float *ref, float *lpc) +{ + int i, j; + float r, error = ac[0]; + + if (ac[0] == 0) { + for (i = 0; i < P_MAX; i++) ref[i] = 0; + return 0; + } + + for (i = 0; i < P_MAX; i++) { + + r = -ac[i + 1]; + for (j = 0; j < i; j++) r -= lpc[j] * ac[i - j]; + ref[i] = r /= error; + + // Update LPC coefficients and total error. + lpc[i] = r; + for (j = 0; j < i / 2; j++) { + float tmp = lpc[j]; + lpc[j] = r * lpc[i - 1 - j]; + lpc[i - 1 - j] += r * tmp; + } + if (i % 2) lpc[j] += lpc[j] * r; + + error *= 1 - r * r; + } + return error; +} +*/ +/* I. Schur's recursion from 1917 is related to the Levinson-Durbin method, + * but faster on parallel architectures; where Levinson-Durbin would take time + * proportional to p * log(p), Schur only requires time proportional to p. The + * GSM coder uses an integer version of the Schur recursion. + * @param in: [0...p] autocorrelation values + * @param out: [0...p-1] reflection coefficients + * @return the minimum mean square error + */ +static float schur(float const *ac, float *ref) +{ + int i, m; + float error=ac[0], r, G[2][P_MAX]; + + if (ac[0] == 0.0) { + for (i = 0; i < P_MAX; i++) ref[i] = 0; + return 0; + } + + /* Initialize the rows of the generator matrix G to ac[1...p]. */ + for (i = 0; i < P_MAX; i++) G[0][i] = G[1][i] = ac[i + 1]; + + for (i = 0;;) { + /* Calculate this iteration's reflection coefficient and error. */ + ref[i] = r = -G[1][0] / error; + error += G[1][0] * r; + + if (++i >= P_MAX) return error; + + /* Update the generator matrix. Unlike Levinson-Durbin's summing of + * reflection coefficients, this loop could be executed in parallel + * by p processors in constant time. + */ + for (m = 0; m < P_MAX - i; m++) { + G[1][m] = G[1][m + 1] + r * G[0][m]; + G[0][m] = G[1][m + 1] * r + G[0][m]; + } + } +} + + + /* 0..7 IN/OUT */ +static void rToLAR(int *r) +/* + * The following scaling for r[..] and LAR[..] has been used: + * + * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. + * LAR[..] = integer( real_LAR[..] * 16384 ); + * with -1.625 <= real_LAR <= 1.625 + */ +{ + int temp; + int i; + + /* Computation of the LAR[0..7] from the r[0..7] + */ + for (i = 0; i < 8; i++) { + temp = abs(r[i]); //GSM_ABS(temp); + if (temp < 22118) { + temp >>= 1; + } else if (temp < 31130) { + temp -= 11059; + } else { + temp -= 26112; + temp <<= 2; + } + r[i] = r[i] < 0 ? -temp : temp; + } +} + +static void quantizeLARs(int *LARs, int *qLARs) +{ int qA[]={20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; + int qB[]={0, 0, 2048, -2560, 94, -1792, -341, -1144}; + int qMin[]={-32, -32, -16, -16, -8, -8, -4, -4}; + int qMax[]={31, 31, 15, 15, 7, 7, 3, 3}; + int i; + for (i = 0; i < 8; i++) { + int temp; + temp = (((LARs[i] * qA[i]) >> 15) + qB[i] + 256) >> 9; + if (temp < qMin[i]) temp = 0; + else if (temp > qMax[i]) temp = qMax[i] - qMin[i]; + else temp = temp - qMin[i]; + qLARs[i] = temp; + } +} + +void lpcAnalysis(gsm_state *state, short *in) +{ float error; + float samples[160]; + float ac[9]; + float ref[8]; + int i; + int * qLARs = state->qLARs; + for (i = 0; i < 160; i++) { + samples[i] = in[i]; + } + autocorrelation(160, samples, 9, ac); + error=schur(ac, ref); + /* + printf("reff: "); + for (i=0;i<8;i++) { + printf("%5.5f ", ref[i]);//((float)i_lpc[i])/32768.0f); + } + printf("\n"); + */ + for (i = 0; i < 8; i++) { + qLARs[i] = (int) (32768 * ref[i]); + } + rToLAR(qLARs); + quantizeLARs(qLARs, qLARs); +} diff --git a/!NotAdopted/Tlen/codec/gsm_preprocess.c b/!NotAdopted/Tlen/codec/gsm_preprocess.c new file mode 100644 index 0000000000..b3d11bb7b1 --- /dev/null +++ b/!NotAdopted/Tlen/codec/gsm_preprocess.c @@ -0,0 +1,103 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "gsm.h" +#include + +/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION + * + * After A-law to linear conversion (or directly from the + * Ato D converter) the following scaling is assumed for + * input to the RPE-LTP algorithm: + * + * + * Where S is the sign bit, v a valid bit, and * a "don't care" bit. + * The original signal is called sop[..] + * + */ + + +void gsm_preprocessing( gsm_state *state, short *in, short *out) +{ + int z1 = state->z1; + int z2 = state->z2; + int mp = state->mp; + int so, s1; + int msp, lsp; + + int k = 160; + + while (k--) { + /* Downscaling of the input signal + * in: 0.1.....................12 + * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.* + * out: 0.1................... 12 + * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0 + */ + so = (*in >> 3) << 2; + in++; + /* 4.2.2 Offset compensation + * + * This part implements a high-pass filter and requires extended + * arithmetic precision for the recursive part of this filter. + * The input of this procedure is the array so[0...159] and the + * output the array sof[ 0...159 ]. + */ + /* Compute the non-recursive part + */ + s1 = (so - z1) << 15; + z1 = so; + msp = z2 >> 15; + lsp = z2 - (msp << 15); + s1 += ((lsp * 32735) + 16384) >> 15; + z2 = msp * 32735 + s1; + /* 4.2.3 Preemphasis + */ + msp = (-28180 * mp + 16384) >> 15; + mp = (z2 + 16384) >> 15; + *out++ = mp + msp; + } + state->z1 = z1; + state->z2 = z2; + state->mp = mp; +/* + printf("preprocessed: \n"); + for (k=0;k<160;k++) { + printf("%7d ", out[k]);//((float)i_lpc[i])/32768.0f); + } + printf("\n"); + */ +} + +void gsm_postprocessing( gsm_state *state, short *in, short *out) +{ + int k; + int msr = state->msr; + for (k = 160; k--; in++, out++) { + msr = *in + ((msr * 28180 + 16384) >>15); /* Deemphasis */ + *out = (msr + msr ) & 0xFFF8; /* Truncation & Upscaling */ + } + state->msr = msr; +} diff --git a/!NotAdopted/Tlen/codec/gsm_rpe.c b/!NotAdopted/Tlen/codec/gsm_rpe.c new file mode 100644 index 0000000000..ad7234e606 --- /dev/null +++ b/!NotAdopted/Tlen/codec/gsm_rpe.c @@ -0,0 +1,248 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "gsm.h" +#include +#include +#include + +static const int gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; +static const int gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; +static const int gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; +/* + * The coefficients of the weighting filter are stored in the gsm_H table. + * The following scaling is used: + * + * gsm_H[0..10] = integer( real_H[ 0..10] * 8192 ); + */ +static void weightingFilter (int *e, int *x) +{ + int L_result; + int k, i; + for (k = 0; k < 40; k++) { + L_result = 4096; + for (i = 0; i < 11; i++) { + int ix = i + k; + if (ix>4 && ix<45) L_result += e[ix - 5] * gsm_H[i]; + } + L_result >>= 13; + x[k] = (L_result < -32768 ? -32768 : (L_result > 32767 ? 32767 : L_result)); + } +} + +/* + * The signal x[0..39] is used to select the RPE grid which is + * represented by Mc. + */ +static void gridSelection( int *x, int *xM, int *Mc_out) +{ + int m, i; + int L_result, L_temp; + int EM, Mc; + + EM = 0; + Mc = 0; + + for (m = 0; m < 4; m++) { + L_result = 0; + for (i = 0; i < 13; i++) { + int temp = x[m + 3*i] >> 2; + L_temp = temp * temp << 1; + L_result += L_temp; + } + if (L_result > EM) { + Mc = m; + EM = L_result; + } + } + /* Down-sampling by a factor 3 to get the selected xM[0..12] + * RPE sequence. + */ + for (i = 0; i < 13; i ++) xM[i] = x[Mc + 3*i]; + *Mc_out = Mc; +} + +/* + * This procedure computes the reconstructed long term residual signal + * ep[0..39] for the LTP analysis filter. The inputs are the Mc + * which is the grid position selection and the xMp[0..12] decoded + * RPE samples which are upsampled by a factor of 3 by inserting zero + * values. + */ +static void gridPositioning (int Mc, int *xMp, int *ep) +{ + int i, k; + for (k = 0; k < 40; k++) ep[k] = 0; + for (i = 0; i < 13; i++) { + ep[ Mc + (3*i) ] = xMp[i]; + } +} + +static void APCMXmaxcToExpMant (int xmaxc, int *exp_out, int *mant_out ) +{ + int exp, mant; + /* Compute exponent and mantissa of the decoded version of xmaxc + */ + exp = 0; + if (xmaxc > 15) exp = (xmaxc >> 3) - 1; + mant = xmaxc - (exp << 3); + + if (mant == 0) { + exp = -4; + mant = 7; + } + else { + while (mant < 8) { + mant = mant << 1 | 1; + exp--; + } + mant -= 8; + } + + *exp_out = exp; + *mant_out = mant; +} + +static void APCMQuantization (int *xM, int *xMc, int *mant_out, int *exp_out, int *xmaxc_out) +{ + int i, itest; + int xmax, xmaxc, temp, temp1, temp2; + int exp, mant; + + + /* Find the maximum absolute value xmax of xM[0..12]. + */ + + xmax = 0; + for (i = 0; i < 13; i++) { + temp = abs(xM[i]); + if (temp > xmax) xmax = temp; + } + if (xmax > 32767) xmax = 32767; + /* Qantizing and coding of xmax to get xmaxc. + */ + + exp = 0; + temp = xmax >> 9; + itest = 0; + + for (i = 0; i < 6; i++) { + if (temp != 0) exp++; + temp = temp >> 1; + } + + temp = exp + 5; + + xmaxc = (xmax >> temp) + (exp << 3); + + /* Quantizing and coding of the xM[0..12] RPE sequence + * to get the xMc[0..12] + */ + APCMXmaxcToExpMant( xmaxc, &exp, &mant ); + + /* This computation uses the fact that the decoded version of xmaxc + * can be calculated by using the exponent and the mantissa part of + * xmaxc (logarithmic table). + * So, this method avoids any division and uses only a scaling + * of the RPE samples by a function of the exponent. A direct + * multiplication by the inverse of the mantissa (NRFAC[0..7] + * found in table 4.5) gives the 3 bit coded version xMc[0..12] + * of the RPE samples. + */ + + /* Direct computation of xMc[0..12] using table 4.5 + */ + temp = (mant|8)<<(5+exp); + temp1 = 6 - exp; + temp2 = gsm_NRFAC[ mant ]; + for (i = 0; i < 13; i++) { + xMc[i] = ((xM[i] << temp1) * temp2 >> 27) + 4; + } + + /* NOTE: This equation is used to make all the xMc[i] positive. + */ + + *mant_out = mant; + *exp_out = exp; + *xmaxc_out = xmaxc; +} + +static void APCMDequantization (int *xMc, int mant, int exp, int *xMp) +{ + int i, temp1, temp2, temp3; + temp1 = gsm_FAC[ mant ]; + temp2 = 6 - exp; + if (temp2 <= 0) { + temp3 = 1 >> (1 - temp2); + } else { + temp3 = 1 << (temp2 - 1); + } + for (i = 0; i < 13; i++) { + xMp[i] = ((((((xMc[i]<<1)-7)<<12)*temp1+16384)>>15)+temp3)>>temp2; + } +} + +void encodeRPE(gsm_state *state) +{ int x[40]; + int xM[13], xMp[13]; + int mant, exp; + int *Mc = state->Mc + state->subframe; + int *xMaxc = state->xMaxc + state->subframe; + int *xMc = state->xMc + state->subframe * 13; + int *e = state->e + state->subframe * 40; + //int i; + /* + printf("RPE in: \n"); + for (i=0;i<40;i++) { + printf("%7d ", e[i]); + } + printf("\n"); + */ + weightingFilter(e, x); + /* + printf("RPE weighting filter: \n"); + for (i=0;i<40;i++) { + printf("%7d ", x[i]); + } + printf("\n"); + */ + gridSelection(x, xM, Mc); + APCMQuantization(xM, xMc, &mant, &exp, xMaxc); + /* printf("RPE Mc(grid #)=%d xmaxc=%d mant=%d exp=%d \n", *Mc, *xMaxc, mant, exp); */ + APCMDequantization(xMc, mant, exp, xMp); + gridPositioning(*Mc, xMp, e); +} + +void decodeRPE(gsm_state *state) +{ + int exp, mant; + int xMp[ 13 ]; + int *xMc = state->xMc + state->subframe * 13; + int *e = state->e + state->subframe * 40; + + APCMXmaxcToExpMant(state->xMaxc[state->subframe], &exp, &mant); + APCMDequantization(xMc, mant, exp, xMp); + gridPositioning(state->Mc[state->subframe], xMp, e); +} diff --git a/!NotAdopted/Tlen/codec/gsm_short.c b/!NotAdopted/Tlen/codec/gsm_short.c new file mode 100644 index 0000000000..c461484639 --- /dev/null +++ b/!NotAdopted/Tlen/codec/gsm_short.c @@ -0,0 +1,211 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "gsm.h" +#include +#include +#include +extern void lpcAnalysis(gsm_state *state, short *in); + +/* + * Dequantize LAR coefficients + */ +static void dequantizeLARs(int *qLARs, int *LARs) +{ + int dqA[]={13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708}; + int dqB[]={0, 0, 2048, -2560, 94, -1792, -341, -1144}; + int dqMin[]={-32, -32, -16, -16, -8, -8, -4, -4}; + int i; + for (i = 0; i < 8; i++) { + int temp; + temp = ((((qLARs[i] + dqMin[i]) << 10) - (dqB[i] << 1)) * dqA[i] + 16384) >> 15; + LARs[i] = temp + temp; + } +} +/* + * Interpolate LAR coefficients (samples 0..12) + */ +static void interpolateLARs_0_12 (int *LARpp_j_1, int *LARpp_j, int *LARp) +{ int i; + for (i = 0; i < 8; i++) { + LARp[i] = (LARpp_j_1[i] >> 1) + (LARpp_j_1[i] >> 2) + (LARpp_j[i] >> 2); + } +} +/* + * Interpolate LAR coefficients (samples 13..26) + */ +static void interpolateLARs_13_26 (int *LARpp_j_1, int *LARpp_j, int *LARp) +{ int i; + for (i = 0; i < 8; i++) { + LARp[i] = (LARpp_j_1[i] >> 1) + (LARpp_j[i] >> 1); + } +} +/* + * Interpolate LAR coefficients (samples 27..39) + */ +static void interpolateLARs_27_39 (int *LARpp_j_1, int *LARpp_j, int *LARp) +{ int i; + for (i = 0; i < 8; i++) { + LARp[i] = (LARpp_j[i] >> 1) + (LARpp_j_1[i] >> 2) + (LARpp_j[i] >> 2); + } +} +/* + * Interpolate LAR coefficients (samples 40..159) + */ +static void interpolateLARs_40_159 (int *LARpp_j_1, int *LARpp_j, int *LARp) +{ int i; + for (i = 0; i < 8; i++) { + LARp[i] = LARpp_j[i]; + } +} +/* + * Convert LAR coefficients to reflection coefficients + */ +static void LARToR( int * LARp) +{ + int i; + int temp; + for (i = 0; i < 8; i++) { + temp = abs(LARp[i]); + if (temp < 11059) temp <<= 1; + else if (temp < 20070) temp += 11059; + else temp = (temp >> 2) + 26112; + LARp[i] = LARp[i] < 0 ? -temp : temp; + } +} + +/* + * This procedure computes the short term residual signal d[..] to be fed + * to the RPE-LTP loop from the s[..] signal and from the local rp[..] + * array (quantized reflection coefficients). As the call of this + * procedure can be done in many ways (see the interpolation of the LAR + * coefficient), it is assumed that the computation begins with index + * k_start (for arrays d[..] and s[..]) and stops with index k_end + * (k_start and k_end are defined in 4.2.9.1). This procedure also + * needs to keep the array u[0..7] in memory for each call. + */ +static void shortTermAnalysisFilter (gsm_state * state, int * rp, int len, short * in) +{ + int * u = state->u; + int i; + int di, ui, sav, rpi; + for (; len--; in++) { + di = sav = *in; + for (i = 0; i < 8; i++) { + ui = u[i]; + rpi = rp[i]; + u[i] = sav; + sav = ui + ((rpi * di + 16384) >> 15); + di = di + ((rpi * ui + 16384) >> 15); + } + *in = di; + } +} + +static void shortTermSynthesisFilter(gsm_state * state, int * rrp, int len, short * in, short *out) +{ + int * v = state->v; + int i; + int sri; + for (; len--; in++, out++) { + sri = *in; + for (i = 8; i--;) { + sri -= (rrp[i] * v[i] + 16384) >> 15; + if (sri < -32768) sri = -32768; + else if (sri > 32767) sri = 32767; + v[i+1] = v[i] + ((rrp[i] * sri + 16384) >> 15); + if (v[i+1] < -32768) v[i+1] = -32768; + else if (v[i+1] > 32767) v[i+1] = 32767; + } + *out = v[0] = sri; + } +} + +void shortTermAnalysis(gsm_state *state, short *in) +{ + int * qLARs = state->qLARs; + int * LARpp_j = state->LARpp[state->j]; + int * LARpp_j_1 = state->LARpp[state->j ^1]; + int LARp[8]; +// int i; + + lpcAnalysis(state, in);//i_samples); +/* + printf("short term in: \n"); + for (i=0;i<160;i++) { + printf("%7d ", in[i]);//((float)i_lpc[i])/32768.0f); + } + printf("\n"); + */ + dequantizeLARs(qLARs, LARpp_j); + interpolateLARs_0_12(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermAnalysisFilter(state, LARp, 13, in); + interpolateLARs_13_26(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermAnalysisFilter(state, LARp, 14, in+13); + interpolateLARs_27_39(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermAnalysisFilter(state, LARp, 13, in+27); + interpolateLARs_40_159(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermAnalysisFilter(state, LARp, 120, in+40); + /* + printf("short-term residuals: \n"); + for (i=0;i<160;i++) { + printf("%7d ", in[i]);//((float)i_lpc[i])/32768.0f); + } + printf("\n"); + */ +} + +void shortTermSynthesis(gsm_state *state, short *in, short *out) +{ + int * qLARs = state->qLARs; + int * LARpp_j = state->LARpp[state->j]; + int * LARpp_j_1 = state->LARpp[state->j ^1]; + int LARp[8]; +// int i; + + dequantizeLARs(qLARs, LARpp_j); + interpolateLARs_0_12(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermSynthesisFilter(state, LARp, 13, in, out); + interpolateLARs_13_26(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermSynthesisFilter(state, LARp, 14, in+13, out+13); + interpolateLARs_27_39(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermSynthesisFilter(state, LARp, 13, in+27, out+27); + interpolateLARs_40_159(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermSynthesisFilter(state, LARp, 120, in+40, out+40); + /* + printf("samples[reconstructed]: \n"); + for (i=0;i<160;i++) { + printf("%7d ", out[i]); + } + */ +} -- cgit v1.2.3