changeset 598:5809165fb140

libgsmhr1: integrate DTX functions for speech decoder
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 04 Dec 2025 09:51:11 +0000
parents e8418167eb1f
children 762cf36e2487
files libgsmhr1/Makefile libgsmhr1/dec_func.c libgsmhr1/dec_func.h libgsmhr1/dec_state.h libgsmhr1/dtx_dec.c libgsmhr1/dtx_dec.h libgsmhr1/namespace.list
diffstat 7 files changed, 276 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libgsmhr1/Makefile	Thu Dec 04 06:44:27 2025 +0000
+++ b/libgsmhr1/Makefile	Thu Dec 04 09:51:11 2025 +0000
@@ -1,9 +1,9 @@
-OBJS=	dec_func.o dec_state.o dhf_packed.o dhf_params.o dtx_rxfe.o \
+OBJS=	dec_func.o dec_state.o dhf_packed.o dhf_params.o dtx_dec.o dtx_rxfe.o \
 	enc_out_order.o mathdp31.o mathhalf.o pack_frame.o paramval_cod.o \
 	paramval_common.o paramval_dec.o rtp_in.o rtp_in_direct.o rxfe.o \
 	rxfe_create.o sid_cw_params.o sid_detect.o sid_reset.o sp_rom.o tfo.o \
 	twts002_in.o twts002_out.o unpack_frame.o
-HDRS=	dec_func.h dec_state.h dtx_const.h dtx_rxfe.h enc_out_order.h \
+HDRS=	dec_func.h dec_state.h dtx_const.h dtx_dec.h dtx_rxfe.h enc_out_order.h\
 	mathdp31.h mathhalf.h namespace.h rxfe.h sp_rom.h tw_gsmhr.h typedefs.h
 LIB=	libgsmhr1.a
 
--- a/libgsmhr1/dec_func.c	Thu Dec 04 06:44:27 2025 +0000
+++ b/libgsmhr1/dec_func.c	Thu Dec 04 09:51:11 2025 +0000
@@ -3487,7 +3487,7 @@
  **************************************************************************/
 
 void   rcToCorrDpL(Shortword swAshift, Shortword swAscale,
-                          Shortword pswRc[], Longword pL_R[])
+                          const Shortword pswRc[], Longword pL_R[])
 {
 
 /*_________________________________________________________________________
--- a/libgsmhr1/dec_func.h	Thu Dec 04 06:44:27 2025 +0000
+++ b/libgsmhr1/dec_func.h	Thu Dec 04 09:51:11 2025 +0000
@@ -83,7 +83,7 @@
                         Shortword pswA[]);
 
   void   rcToCorrDpL(Shortword swAshift, Shortword swAscale,
-                            Shortword pswRc[], Longword pL_R[]);
+                            const Shortword pswRc[], Longword pL_R[]);
 
   void   res_eng(Shortword pswReflecCoefIn[], Shortword swRq,
                         struct NormSw *psnsSqrtRsOut);
--- a/libgsmhr1/dec_state.h	Thu Dec 04 06:44:27 2025 +0000
+++ b/libgsmhr1/dec_state.h	Thu Dec 04 09:51:11 2025 +0000
@@ -33,7 +33,13 @@
 	Shortword pswLtpStateBaseDec[LTP_LEN + S_LEN];
 	Shortword pswPPreState[LTP_LEN + S_LEN];
 	Shortword swMuteFlagOld;
+	/* comfort noise interpolation */
 	Shortword swRxDTXState;
+	Shortword swR0OldCN;
+	Shortword swR0NewCN;
+	Longword pL_OldCorrSeq[NP + 1];
+	Longword pL_NewCorrSeq[NP + 1];
+	Longword pL_CorrSeq[NP + 1];
 };
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgsmhr1/dtx_dec.c	Thu Dec 04 09:51:11 2025 +0000
@@ -0,0 +1,238 @@
+/***************************************************************************
+ *
+ *   File Name: dtx_dec.c
+ *
+ *   Derivation: this module is the subset of GSM 06.06 dtx.c
+ *   reduced to decoder functions that aren't in dtx_rxfe.c, i.e.,
+ *   apply only to the full decoder and not the TFO transform.
+ *
+ **************************************************************************/
+
+/*________________________________________________________________________
+ |                                                                        |
+ |                         Include Files                                  |
+ |________________________________________________________________________|
+*/
+
+#include <string.h>
+#include "typedefs.h"
+#include "namespace.h"
+#include "mathhalf.h"
+#include "mathdp31.h"
+#include "dec_func.h"
+#include "dec_state.h"
+#include "dtx_const.h"
+#include "dtx_dec.h"
+
+/*________________________________________________________________________
+ |                                                                        |
+ |                            Defines                                     |
+ |________________________________________________________________________|
+*/
+
+#define ASHIFT 4
+#define ASCALE 0x0800
+
+
+/*________________________________________________________________________
+ |                                                                        |
+ |                         DTX Rom Tables                                 |
+ |________________________________________________________________________|
+*/
+
+/* interpolation curve for comfort noise (i*1/12) i=1..12 */
+static const Shortword psrCNNewFactor[12] = {
+	0x0aaa, 0x1554, 0x1ffe, 0x2aa8, 0x3552,
+	0x3ffc, 0x4aa6, 0x5550, 0x5ffa, 0x6aa4,
+	0x754e, 0x7fff
+};
+
+
+/*
+ * This function is a fragment from original rxInterpR0Lpc():
+ * init or update CN interpolation endpoints on CNIFIRSTSID
+ * or CNICONT.
+ */
+void Init_CN_interpolation(struct gsmhr_decoder_state *st, Shortword deco_mode,
+			   Shortword new_R0, const Shortword *pswNewKs)
+{
+	st->swR0OldCN = st->swOldR0Dec;
+	st->swR0NewCN = new_R0;
+	if (deco_mode == CNIFIRSTSID) {
+		rcToCorrDpL(ASHIFT, ASCALE, st->pswOldFrmKsDec,
+			    st->pL_OldCorrSeq);
+	} else {
+		memcpy(st->pL_OldCorrSeq, st->pL_CorrSeq,
+			sizeof(st->pL_CorrSeq));
+	}
+	rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, st->pL_NewCorrSeq);
+}
+
+/*
+ * This function is a fragment from original rxInterpR0Lpc():
+ * interpolate R0 for CN output.
+ */
+Shortword CN_Interpolate_R0(struct gsmhr_decoder_state *st)
+{
+	return linInterpSidShort(st->swR0NewCN, st->swR0OldCN,
+				 st->swRxDTXState);
+}
+
+/*
+ * This function is a fragment from original rxInterpR0Lpc():
+ * interpolate LPC for CN output.
+ */
+void CN_Interpolate_LPC(struct gsmhr_decoder_state *st, Shortword *pswNewKs)
+{
+    int i;
+
+    /* linearly interpolate between the two sets of correlation coefs */
+    /* -------------------------------------------------------------- */
+
+    for (i = 0; i < NP + 1; i++)
+    {
+      st->pL_CorrSeq[i] = linInterpSid(st->pL_NewCorrSeq[i],
+					st->pL_OldCorrSeq[i],
+					st->swRxDTXState);
+    }
+
+    /* Generate this frames K's (overwrite input) */
+    /* ------------------------------------------ */
+
+    aFlatRcDp(st->pL_CorrSeq, pswNewKs);
+}
+
+
+/*************************************************************************
+ *
+ *   FUNCTION NAME: linInterpSid
+ *
+ *   PURPOSE:
+ *
+ *     Linearly interpolate between two input numbers based on what the
+ *     current DtxState is.
+ *
+ *   INPUTS:
+ *
+ *     L_New - longword more current value
+ *
+ *     L_Old - longword oldest value
+ *
+ *     swDtxState - state is 0 at the transmitted SID Frame.
+ *
+ *
+ *   OUTPUTS:
+ *
+ *     none
+ *
+ *   RETURN VALUE:
+ *
+ *     A value between old and new inputs with dtxState+1/12 of the new
+ *     (dtxState+1)-12/12 of the old
+ *
+ *
+ *************************************************************************/
+
+Longword linInterpSid(Longword L_New, Longword L_Old, Shortword swDtxState)
+{
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                            Automatic Variables                          |
+ |_________________________________________________________________________|
+*/
+
+  Shortword swOldFactor;
+
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                              Executable Code                            |
+ |_________________________________________________________________________|
+*/
+
+  /* old factor = (1.0 - newFactor) */
+  /* ------------------------------ */
+
+  swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]);
+  swOldFactor = add(0x1, swOldFactor);
+
+
+  /* contributions from new and old */
+  /* ------------------------------ */
+
+  L_New = L_mpy_ls(L_New, psrCNNewFactor[swDtxState]);
+  L_Old = L_mpy_ls(L_Old, swOldFactor);
+
+  return (L_add(L_New, L_Old));
+
+}
+
+
+/*************************************************************************
+ *
+ *   FUNCTION NAME: linInterpSidShort
+ *
+ *   PURPOSE:
+ *
+ *     Linearly interpolate between two input numbers based on what
+ *     the current DtxState is.
+ *
+ *   INPUTS:
+ *
+ *     swNew - 16 bit,  more current value
+ *
+ *     swOld - 16 bit, oldest value
+ *
+ *     swDtxState - state is 0 at the transmitted SID Frame.
+ *
+ *
+ *   OUTPUTS:
+ *
+ *     none
+ *
+ *   RETURN VALUE:
+ *
+ *     A value between old and new inputs with dtxState+1/12 of the new
+ *     (dtxState+1)-12/12 of the old
+ *
+ *************************************************************************/
+
+Shortword linInterpSidShort(Shortword swNew, Shortword swOld,
+                                   Shortword swDtxState)
+{
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                            Automatic Variables                          |
+ |_________________________________________________________________________|
+*/
+
+  Shortword swOldFactor;
+  Longword L_New,
+         L_Old;
+
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                              Executable Code                            |
+ |_________________________________________________________________________|
+*/
+
+  /* old factor = (1.0 - newFactor) */
+  /* ------------------------------ */
+
+  swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]);
+  swOldFactor = add(0x1, swOldFactor);
+
+
+  /* contributions from new and old */
+  /* ------------------------------ */
+
+  L_New = L_mult(swNew, psrCNNewFactor[swDtxState]);
+  L_Old = L_mult(swOld, swOldFactor);
+
+
+  return (round(L_add(L_New, L_Old)));
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgsmhr1/dtx_dec.h	Thu Dec 04 09:51:11 2025 +0000
@@ -0,0 +1,25 @@
+#ifndef __DTX_DEC
+#define __DTX_DEC
+
+#include "typedefs.h"
+#include "tw_gsmhr.h"
+
+/*________________________________________________________________________
+ |                                                                        |
+ |                      Function Prototypes                               |
+ |________________________________________________________________________|
+*/
+
+Longword linInterpSid(Longword L_New, Longword L_Old, Shortword swDtxState);
+
+Shortword linInterpSidShort(Shortword swNew, Shortword swOld,
+			    Shortword swDtxState);
+
+void Init_CN_interpolation(struct gsmhr_decoder_state *st, Shortword deco_mode,
+			   Shortword new_R0, const Shortword *pswNewKs);
+
+Shortword CN_Interpolate_R0(struct gsmhr_decoder_state *st);
+
+void CN_Interpolate_LPC(struct gsmhr_decoder_state *st, Shortword *pswNewKs);
+
+#endif
--- a/libgsmhr1/namespace.list	Thu Dec 04 06:44:27 2025 +0000
+++ b/libgsmhr1/namespace.list	Thu Dec 04 09:51:11 2025 +0000
@@ -27,3 +27,6 @@
 aFlatRcDp b_con fp_ex g_corr1 g_corr1s getSfrmLpc get_ipjj interpolateCheck
 lpcFir lpcIir lpcIrZsIir lpcZiIir lpcZsFir lpcZsIir lpcZsIirP r0BasedEnergyShft
 rcToADp rcToCorrDpL res_eng rs_rr rs_rrNs scaleExcite sqroot v_con
+
+linInterpSid linInterpSidShort
+Init_CN_interpolation CN_Interpolate_R0 CN_Interpolate_LPC