diff libgsmhr1/dtx_dec.c @ 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
children c7c03231002d
line wrap: on
line diff
--- /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)));
+
+}