comparison sp_enc.c @ 0:9008dbc8ca74

import original C code from GSM 06.06
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 14 Jun 2024 23:27:16 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:9008dbc8ca74
1 /***************************************************************************
2 *
3 * File Name: sp_enc.c
4 *
5 * Purpose: Contains speech encoder function. Calls are made to the
6 * frame-based encoding functions (see sp_frm.c), and the subframe-
7 * based encoding function (see sp_sfrm.c)
8 *
9 * Functions in this file (only 1)
10 * speechEncoder()
11 *
12 **************************************************************************/
13 /*_________________________________________________________________________
14 | |
15 | Include Files |
16 |_________________________________________________________________________|
17 */
18
19 #include "mathhalf.h"
20 #include "mathdp31.h"
21 #include "sp_rom.h"
22 #include "sp_dec.h"
23 #include "sp_frm.h"
24 #include "sp_sfrm.h"
25 #include "sp_enc.h"
26 #include "host.h"
27 #include "vad.h"
28
29 /*_________________________________________________________________________
30 | |
31 | Local Defines |
32 |_________________________________________________________________________|
33 */
34
35 #define CG_INT_MACS 6 /* Number of Multiply-Accumulates in */
36 /* one interpolation */
37 #define ASCALE 0x0800
38 #define LMAX 142 /* largest lag (integer sense) */
39 #define LSMAX (LMAX+ CG_INT_MACS/2) /* Lag Search Array Length */
40 #define NUM_CLOSED 3 /* Maximum number of lags searched */
41 /* in closed loop. */
42
43 #define LPCSTARTINDEX 25 /* Where the LPC analysis window
44 * starts */
45 #define INBUFFSZ LPCSTARTINDEX + A_LEN /* Input buffer size */
46 #define NUMSTARTUPSMP INBUFFSZ - F_LEN /* Number of samples needed */
47 /* at start up */
48 #define NUMSTARTUPSMP_P1 INBUFFSZ - F_LEN + 1
49 #define HPFSHIFT 1 /* no right shifts high pass shifts
50 * speech */
51
52 /*_________________________________________________________________________
53 | |
54 | State variables (globals) |
55 |_________________________________________________________________________|
56 */
57
58 Shortword swOldR0;
59 Shortword swOldR0Index;
60
61 struct NormSw psnsWSfrmEngSpace[2 * N_SUB];
62
63 Shortword pswHPFXState[4];
64 Shortword pswHPFYState[8];
65 Shortword pswOldFrmKs[NP];
66 Shortword pswOldFrmAs[NP];
67 Shortword pswOldFrmSNWCoefs[NP];
68 Shortword pswWgtSpeechSpace[F_LEN + LMAX + CG_INT_MACS / 2];
69
70 Shortword pswSpeech[INBUFFSZ]; /* input speech */
71
72 Shortword swPtch = 1;
73
74 /*_________________________________________________________________________
75 | |
76 | Global DTX variables |
77 |_________________________________________________________________________|
78 */
79
80 Shortword swTxGsHistPtr = 0;
81
82 Shortword pswCNVSCode1[N_SUB],
83 pswCNVSCode2[N_SUB],
84 pswCNGsp0Code[N_SUB],
85 pswCNLpc[3],
86 swCNR0;
87
88
89 extern Longword pL_GsHist[];
90 extern LongwordRom ppLr_gsTable[4][32];
91
92 /***************************************************************************
93 *
94 * FUNCTION NAME: speechEncoder
95 *
96 * PURPOSE:
97 *
98 * Performs GSM half-rate speech encoding on frame basis (160 samples).
99 *
100 * INPUTS:
101 *
102 * pswSpeechIn[0:159] - input speech samples, 160 new samples per frame
103 *
104 * OUTPUTS:
105 *
106 * pswFrmCodes[0:19] - output parameters, 18 speech parameters plus
107 * VAD and SP flags
108 *
109 * RETURN VALUE:
110 *
111 * None
112 *
113 * IMPLEMENTATION:
114 *
115 * n/a
116 *
117 * REFERENCES: Sub-clause 4.1 of GSM Recomendation 06.20
118 *
119 * KEYWORDS: speechcoder, analysis
120 *
121 *************************************************************************/
122
123 void speechEncoder(Shortword pswSpeechIn[], Shortword pswFrmCodes[])
124 {
125
126 /*_________________________________________________________________________
127 | |
128 | Static Variables |
129 |_________________________________________________________________________|
130 */
131
132 /* 1st point in analysis window */
133 static Shortword *pswLpcStart = &pswSpeech[LPCSTARTINDEX];
134
135 /* 1st point of new frame other than 1st */
136 static Shortword *pswNewSpeech = &pswSpeech[NUMSTARTUPSMP];
137
138 /* sample 0 of weighted speech */
139 static Shortword *pswWgtSpeech = &pswWgtSpeechSpace[LSMAX];
140
141 static struct NormSw *psnsWSfrmEng = &psnsWSfrmEngSpace[N_SUB];
142
143 /*_________________________________________________________________________
144 | |
145 | Automatic Variables |
146 |_________________________________________________________________________|
147 */
148
149 int iVoicing, /* bitAlloc */
150 iR0, /* bitAlloc and aflat */
151 piVq[3], /* bitAlloc */
152 iSi, /* bitAlloc */
153 piLagCode[N_SUB], /* bitAlloc */
154 piVSCode1[N_SUB], /* bitAlloc */
155 piVSCode2[N_SUB], /* bitAlloc */
156 piGsp0Code[N_SUB]; /* bitAlloc */
157
158 short int siUVCode,
159 siSi,
160 i,
161 j;
162
163 Shortword swR0,
164 pswLagCode[N_SUB],
165 pswVSCode1[N_SUB],
166 pswVSCode2[N_SUB],
167 pswGsp0Code[N_SUB],
168 *pswLagListPtr,
169 pswFrmKs[NP],
170 pswFrmAs[NP],
171 pswFrmSNWCoefs[NP],
172 pswLagList[N_SUB * NUM_CLOSED],
173 pswNumLagList[N_SUB],
174 pswPitchBuf[N_SUB],
175 pswHNWCoefBuf[N_SUB],
176 ppswSNWCoefAs[N_SUB][NP],
177 ppswSynthAs[N_SUB][NP];
178
179 Shortword swSP,
180 pswVadLags[4], /* VAD Parameters */
181 swVadFlag; /* flag indicating voice activity
182 * detector state. 1 = speech or
183 * speech/signal present */
184 struct NormSw
185 psnsSqrtRs[N_SUB];
186
187 /*_________________________________________________________________________
188 | |
189 | Executable Code |
190 |_________________________________________________________________________|
191 */
192
193 /* Speech frame processing */
194 /* High pass filter the speech */
195 /* ---------------------------- */
196
197 filt4_2nd(psrHPFCoefs, pswSpeechIn,
198 pswHPFXState, pswHPFYState, F_LEN, HPFSHIFT);
199
200 /* copy high passed filtered speech into encoder's speech buff */
201 /*-------------------------------------------------------------*/
202
203 for (i = 0; i < F_LEN; i++)
204 pswNewSpeech[i] = pswSpeechIn[i];
205
206
207
208
209 /* Calculate and quantize LPC coefficients */
210 /* --------------------------------------- */
211
212 aflat(pswLpcStart, &iR0, pswFrmKs, piVq,
213 swPtch, &swVadFlag, &swSP);
214
215
216 /* Lookup frame energy r0 */
217 /* ---------------------- */
218
219 swR0 = psrR0DecTbl[iR0 * 2]; /* lookupR0 */
220
221 /* Generate the direct form coefs */
222 /* ------------------------------ */
223
224 if (!rcToADp(ASCALE, pswFrmKs, pswFrmAs))
225 {
226
227 getNWCoefs(pswFrmAs, pswFrmSNWCoefs);
228 }
229 else
230 {
231
232 for (i = 0; i < NP; i++)
233 {
234 pswFrmKs[i] = pswOldFrmKs[i];
235 pswFrmAs[i] = pswOldFrmAs[i];
236 pswFrmSNWCoefs[i] = pswOldFrmSNWCoefs[i];
237 }
238 }
239
240 /* Interpolate, or otherwise get sfrm reflection coefs */
241 /* --------------------------------------------------- */
242
243 getSfrmLpcTx(swOldR0, swR0,
244 pswOldFrmKs, pswOldFrmAs,
245 pswOldFrmSNWCoefs,
246 pswFrmKs, pswFrmAs,
247 pswFrmSNWCoefs,
248 pswSpeech,
249 &siSi,
250 psnsSqrtRs,
251 ppswSynthAs, ppswSNWCoefAs);
252
253 /* loose once bitAlloc done */
254 iSi = siSi;
255
256 /* Weight the entire speech frame */
257 /* ------------------------------ */
258
259 weightSpeechFrame(pswSpeech, ppswSynthAs[0], ppswSNWCoefAs[0],
260 pswWgtSpeechSpace);
261
262 /* Perform open-loop lag search, get harmonic-noise-weighting parameters */
263 /* --------------------------------------------------------------------- */
264
265 openLoopLagSearch(&pswWgtSpeechSpace[LSMAX],
266 swOldR0Index,
267 (Shortword) iR0,
268 &siUVCode,
269 pswLagList,
270 pswNumLagList,
271 pswPitchBuf,
272 pswHNWCoefBuf,
273 &psnsWSfrmEng[0],
274 pswVadLags,
275 swSP);
276
277 iVoicing = siUVCode;
278
279
280 /* Using open loop LTP data to calculate swPtch */ /* DTX mode */
281 /* parameter */ /* DTX mode */
282 /* -------------------------------------------- */ /* DTX mode */
283
284 periodicity_update(pswVadLags, &swPtch); /* DTX mode */
285
286
287 /* Subframe processing loop */
288 /* ------------------------ */
289
290 pswLagListPtr = pswLagList;
291
292 for (giSfrmCnt = 0; giSfrmCnt < N_SUB; giSfrmCnt++)
293 {
294
295 if (swSP == 0) /* DTX mode */
296 { /* DTX mode */
297 pswVSCode1[giSfrmCnt] = pswCNVSCode1[giSfrmCnt]; /* DTX mode */
298 pswVSCode2[giSfrmCnt] = pswCNVSCode2[giSfrmCnt]; /* DTX mode */
299 pswGsp0Code[giSfrmCnt] = pswCNGsp0Code[giSfrmCnt]; /* DTX mode */
300 } /* DTX mode */
301
302 sfrmAnalysis(&pswWgtSpeech[giSfrmCnt * S_LEN],
303 siUVCode,
304 psnsSqrtRs[giSfrmCnt],
305 ppswSNWCoefAs[giSfrmCnt],
306 pswLagListPtr,
307 pswNumLagList[giSfrmCnt],
308 pswPitchBuf[giSfrmCnt],
309 pswHNWCoefBuf[giSfrmCnt],
310 &pswLagCode[giSfrmCnt], &pswVSCode1[giSfrmCnt],
311 &pswVSCode2[giSfrmCnt], &pswGsp0Code[giSfrmCnt],
312 swSP);
313
314 pswLagListPtr = &pswLagListPtr[pswNumLagList[giSfrmCnt]];
315
316 }
317
318
319 /* copy comfort noise parameters, */ /* DTX mode */
320 /* update GS history */ /* DTX mode */
321 /* ------------------------------ */ /* DTX mode */
322
323 if (swSP == 0) /* DTX mode */
324 { /* DTX mode */
325
326 /* copy comfort noise frame parameter */ /* DTX mode */
327 /* ---------------------------------- */ /* DTX mode */
328
329 iR0 = swCNR0; /* quantized R0 index */ /* DTX mode */
330 for (i=0; i < 3; i++) /* DTX mode */
331 piVq[i] = pswCNLpc[i]; /* DTX mode */
332
333 } /* DTX mode */
334 else /* DTX mode */
335 { /* DTX mode */
336
337 /* if swSP != 0, then update the GS history */ /* DTX mode */
338 /* -----------------------------------------*/ /* DTX mode */
339
340 for (i=0; i < N_SUB; i++){ /* DTX mode */
341 pL_GsHist[swTxGsHistPtr] = /* DTX mode */
342 ppLr_gsTable[siUVCode][pswGsp0Code[i]]; /* DTX mode */
343 swTxGsHistPtr++; /* DTX mode */
344 if (swTxGsHistPtr > ((OVERHANG-1)*N_SUB)-1) /* DTX mode */
345 swTxGsHistPtr=0; /* DTX mode */
346 } /* DTX mode */
347
348 } /* DTX mode */
349
350
351 /* End of frame processing, update frame based parameters */
352 /* ------------------------------------------------------ */
353
354 for (i = 0; i < N_SUB; i++)
355 {
356 piLagCode[i] = pswLagCode[i];
357 piVSCode1[i] = pswVSCode1[i];
358 piVSCode2[i] = pswVSCode2[i];
359 piGsp0Code[i] = pswGsp0Code[i];
360 }
361
362 swOldR0Index = (Shortword) iR0;
363 swOldR0 = swR0;
364
365 for (i = 0; i < NP; i++)
366 {
367 pswOldFrmKs[i] = pswFrmKs[i];
368 pswOldFrmAs[i] = pswFrmAs[i];
369 pswOldFrmSNWCoefs[i] = pswFrmSNWCoefs[i];
370 }
371
372 /* Insert SID Codeword */ /* DTX mode */
373 /* ------------------- */ /* DTX mode */
374
375 if (swSP == 0) /* DTX mode */
376 { /* DTX mode */
377 iVoicing = 0x0003; /* 2 bits */ /* DTX mode */
378 iSi = 0x0001; /* 1 bit */ /* DTX mode */
379 for (i=0; i < N_SUB; i++) /* DTX mode */
380 { /* DTX mode */
381 piVSCode1[i] = 0x01ff; /* 9 bits */ /* DTX mode */
382 piGsp0Code[i] = 0x001f; /* 5 bits */ /* DTX mode */
383 }
384 piLagCode[0] = 0x00ff; /* 8 bits */ /* DTX mode */
385 piLagCode[1] = 0x000f; /* 4 bits */ /* DTX mode */
386 piLagCode[2] = 0x000f; /* 4 bits */ /* DTX mode */
387 piLagCode[3] = 0x000f; /* 4 bits */ /* DTX mode */
388 } /* DTX mode */
389
390
391 /* Generate encoded parameter array */
392 /* -------------------------------- */
393
394 fillBitAlloc(iVoicing, iR0, piVq, iSi, piLagCode,
395 piVSCode1, piVSCode2,
396 piGsp0Code, swVadFlag, swSP, pswFrmCodes);
397
398
399 /* delay the input speech by 1 frame */
400 /*-----------------------------------*/
401
402 for (i = 0, j = F_LEN; j < INBUFFSZ; i++, j++)
403 {
404 pswSpeech[i] = pswSpeech[j];
405 }
406 }