comparison 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
comparison
equal deleted inserted replaced
597:e8418167eb1f 598:5809165fb140
1 /***************************************************************************
2 *
3 * File Name: dtx_dec.c
4 *
5 * Derivation: this module is the subset of GSM 06.06 dtx.c
6 * reduced to decoder functions that aren't in dtx_rxfe.c, i.e.,
7 * apply only to the full decoder and not the TFO transform.
8 *
9 **************************************************************************/
10
11 /*________________________________________________________________________
12 | |
13 | Include Files |
14 |________________________________________________________________________|
15 */
16
17 #include <string.h>
18 #include "typedefs.h"
19 #include "namespace.h"
20 #include "mathhalf.h"
21 #include "mathdp31.h"
22 #include "dec_func.h"
23 #include "dec_state.h"
24 #include "dtx_const.h"
25 #include "dtx_dec.h"
26
27 /*________________________________________________________________________
28 | |
29 | Defines |
30 |________________________________________________________________________|
31 */
32
33 #define ASHIFT 4
34 #define ASCALE 0x0800
35
36
37 /*________________________________________________________________________
38 | |
39 | DTX Rom Tables |
40 |________________________________________________________________________|
41 */
42
43 /* interpolation curve for comfort noise (i*1/12) i=1..12 */
44 static const Shortword psrCNNewFactor[12] = {
45 0x0aaa, 0x1554, 0x1ffe, 0x2aa8, 0x3552,
46 0x3ffc, 0x4aa6, 0x5550, 0x5ffa, 0x6aa4,
47 0x754e, 0x7fff
48 };
49
50
51 /*
52 * This function is a fragment from original rxInterpR0Lpc():
53 * init or update CN interpolation endpoints on CNIFIRSTSID
54 * or CNICONT.
55 */
56 void Init_CN_interpolation(struct gsmhr_decoder_state *st, Shortword deco_mode,
57 Shortword new_R0, const Shortword *pswNewKs)
58 {
59 st->swR0OldCN = st->swOldR0Dec;
60 st->swR0NewCN = new_R0;
61 if (deco_mode == CNIFIRSTSID) {
62 rcToCorrDpL(ASHIFT, ASCALE, st->pswOldFrmKsDec,
63 st->pL_OldCorrSeq);
64 } else {
65 memcpy(st->pL_OldCorrSeq, st->pL_CorrSeq,
66 sizeof(st->pL_CorrSeq));
67 }
68 rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, st->pL_NewCorrSeq);
69 }
70
71 /*
72 * This function is a fragment from original rxInterpR0Lpc():
73 * interpolate R0 for CN output.
74 */
75 Shortword CN_Interpolate_R0(struct gsmhr_decoder_state *st)
76 {
77 return linInterpSidShort(st->swR0NewCN, st->swR0OldCN,
78 st->swRxDTXState);
79 }
80
81 /*
82 * This function is a fragment from original rxInterpR0Lpc():
83 * interpolate LPC for CN output.
84 */
85 void CN_Interpolate_LPC(struct gsmhr_decoder_state *st, Shortword *pswNewKs)
86 {
87 int i;
88
89 /* linearly interpolate between the two sets of correlation coefs */
90 /* -------------------------------------------------------------- */
91
92 for (i = 0; i < NP + 1; i++)
93 {
94 st->pL_CorrSeq[i] = linInterpSid(st->pL_NewCorrSeq[i],
95 st->pL_OldCorrSeq[i],
96 st->swRxDTXState);
97 }
98
99 /* Generate this frames K's (overwrite input) */
100 /* ------------------------------------------ */
101
102 aFlatRcDp(st->pL_CorrSeq, pswNewKs);
103 }
104
105
106 /*************************************************************************
107 *
108 * FUNCTION NAME: linInterpSid
109 *
110 * PURPOSE:
111 *
112 * Linearly interpolate between two input numbers based on what the
113 * current DtxState is.
114 *
115 * INPUTS:
116 *
117 * L_New - longword more current value
118 *
119 * L_Old - longword oldest value
120 *
121 * swDtxState - state is 0 at the transmitted SID Frame.
122 *
123 *
124 * OUTPUTS:
125 *
126 * none
127 *
128 * RETURN VALUE:
129 *
130 * A value between old and new inputs with dtxState+1/12 of the new
131 * (dtxState+1)-12/12 of the old
132 *
133 *
134 *************************************************************************/
135
136 Longword linInterpSid(Longword L_New, Longword L_Old, Shortword swDtxState)
137 {
138
139 /*_________________________________________________________________________
140 | |
141 | Automatic Variables |
142 |_________________________________________________________________________|
143 */
144
145 Shortword swOldFactor;
146
147
148 /*_________________________________________________________________________
149 | |
150 | Executable Code |
151 |_________________________________________________________________________|
152 */
153
154 /* old factor = (1.0 - newFactor) */
155 /* ------------------------------ */
156
157 swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]);
158 swOldFactor = add(0x1, swOldFactor);
159
160
161 /* contributions from new and old */
162 /* ------------------------------ */
163
164 L_New = L_mpy_ls(L_New, psrCNNewFactor[swDtxState]);
165 L_Old = L_mpy_ls(L_Old, swOldFactor);
166
167 return (L_add(L_New, L_Old));
168
169 }
170
171
172 /*************************************************************************
173 *
174 * FUNCTION NAME: linInterpSidShort
175 *
176 * PURPOSE:
177 *
178 * Linearly interpolate between two input numbers based on what
179 * the current DtxState is.
180 *
181 * INPUTS:
182 *
183 * swNew - 16 bit, more current value
184 *
185 * swOld - 16 bit, oldest value
186 *
187 * swDtxState - state is 0 at the transmitted SID Frame.
188 *
189 *
190 * OUTPUTS:
191 *
192 * none
193 *
194 * RETURN VALUE:
195 *
196 * A value between old and new inputs with dtxState+1/12 of the new
197 * (dtxState+1)-12/12 of the old
198 *
199 *************************************************************************/
200
201 Shortword linInterpSidShort(Shortword swNew, Shortword swOld,
202 Shortword swDtxState)
203 {
204
205 /*_________________________________________________________________________
206 | |
207 | Automatic Variables |
208 |_________________________________________________________________________|
209 */
210
211 Shortword swOldFactor;
212 Longword L_New,
213 L_Old;
214
215
216 /*_________________________________________________________________________
217 | |
218 | Executable Code |
219 |_________________________________________________________________________|
220 */
221
222 /* old factor = (1.0 - newFactor) */
223 /* ------------------------------ */
224
225 swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]);
226 swOldFactor = add(0x1, swOldFactor);
227
228
229 /* contributions from new and old */
230 /* ------------------------------ */
231
232 L_New = L_mult(swNew, psrCNNewFactor[swDtxState]);
233 L_Old = L_mult(swOld, swOldFactor);
234
235
236 return (round(L_add(L_New, L_Old)));
237
238 }