annotate libgsmefr/dec_lag6.c @ 242:f081a6850fb5

libgsmfrp: new refined implementation The previous implementation exhibited the following defects, which are now fixed: 1) The last received valid SID was cached forever for the purpose of handling future invalid SIDs - we could have received some valid SID ages ago, then lots of speech or NO_DATA, and if we then get an invalid SID, we would resurrect the last valid SID from ancient history - a bad design. In our new design, we handle invalid SID based on the current state, much like BFI. 2) GSM 06.11 spec says clearly that after the second lost SID (received BFI=1 && TAF=1 in CN state) we need to gradually decrease the output level, rather than jump directly to emitting silence frames - we previously failed to implement such logic. 3) Per GSM 06.12 section 5.2, Xmaxc should be the same in all 4 subframes in a SID frame. What should we do if we receive an otherwise valid SID frame with different Xmaxc? Our previous approach would replicate this Xmaxc oddity in every subsequent generated CN frame, which is rather bad. In our new design, the very first CN frame (which can be seen as a transformation of the SID frame itself) retains the original 4 distinct Xmaxc, but all subsequent CN frames are based on the Xmaxc from the last subframe of the most recent SID.
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 09 May 2023 05:16:31 +0000
parents f387ee919f2c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*************************************************************************
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * FUNCTION: Dec_lag6
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 *
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 * PURPOSE: Decoding of fractional pitch lag with 1/6 resolution.
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * Extract the integer and fraction parts of the pitch lag from
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 * the received adaptive codebook index.
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 *
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 * See "Enc_lag6.c" for more details about the encoding procedure.
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 *
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 * The fractional lag in 1st and 3rd subframes is encoded with 9 bits
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 * while that in 2nd and 4th subframes is relatively encoded with 6 bits.
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 * Note that in relative encoding only 61 values are used. If the
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 * decoder receives 61, 62, or 63 as the relative pitch index, it means
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 * that a transmission error occurred. In this case, the pitch lag from
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 * previous subframe is used.
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 *
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 *************************************************************************/
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
19 #include "gsm_efr.h"
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 #include "typedef.h"
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
21 #include "namespace.h"
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 #include "basic_op.h"
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
23 #include "no_count.h"
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
24 #include "codec.h"
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
25 #include "cnst.h"
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
26 #include "dec_state.h"
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
28 Word16 Dec_lag6 ( /* output: return integer pitch lag */
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
29 struct EFR_decoder_state *st,
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 Word16 index, /* input : received pitch index */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 Word16 pit_min, /* input : minimum pitch lag */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 Word16 pit_max, /* input : maximum pitch lag */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 Word16 i_subfr, /* input : subframe flag */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 Word16 L_frame_by2,/* input : speech frame size divided by 2 */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 Word16 *T0_frac, /* output: fractional part of pitch lag */
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
36 Word16 bfi, /* input : bad frame indicator */
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
37 Word16 *T0_min,
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
38 Word16 *T0_max
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 )
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 {
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 Word16 pit_flag;
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 Word16 T0, i;
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 pit_flag = i_subfr; move16 (); /* flag for 1st or 3rd subframe */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 test ();
190
f387ee919f2c libgsmefr/dec_lag6.c: perf opt
Mychaela Falconia <falcon@freecalypso.org>
parents: 65
diff changeset
46 if (i_subfr == L_frame_by2)
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 {
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 pit_flag = 0; move16 ();
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 test ();
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 if (pit_flag == 0) /* if 1st or 3rd subframe */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 {
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 test ();
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 if (bfi == 0)
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 { /* if bfi == 0 decode pitch */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 test ();
190
f387ee919f2c libgsmefr/dec_lag6.c: perf opt
Mychaela Falconia <falcon@freecalypso.org>
parents: 65
diff changeset
57 if (index < 463)
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 {
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 /* T0 = (index+5)/6 + 17 */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 T0 = add (mult (add (index, 5), 5462), 17);
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 i = add (add (T0, T0), T0);
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 /* *T0_frac = index - T0*6 + 105 */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 *T0_frac = add (sub (index, add (i, i)), 105);
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 move16 ();
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 else
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 {
190
f387ee919f2c libgsmefr/dec_lag6.c: perf opt
Mychaela Falconia <falcon@freecalypso.org>
parents: 65
diff changeset
68 T0 = index - 368;
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 *T0_frac = 0; move16 ();
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 else
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 /* bfi == 1 */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 {
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
75 T0 = st->old_T0;
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
76 *T0_frac = 0;
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 /* find T0_min and T0_max for 2nd (or 4th) subframe */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
81 *T0_min = sub (T0, 5);
190
f387ee919f2c libgsmefr/dec_lag6.c: perf opt
Mychaela Falconia <falcon@freecalypso.org>
parents: 65
diff changeset
82 if (*T0_min < pit_min)
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 {
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
84 *T0_min = pit_min;
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 }
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
86 *T0_max = add (*T0_min, 9);
190
f387ee919f2c libgsmefr/dec_lag6.c: perf opt
Mychaela Falconia <falcon@freecalypso.org>
parents: 65
diff changeset
87 if (*T0_max > pit_max)
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 {
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
89 *T0_max = pit_max;
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
90 *T0_min = sub (*T0_max, 9);
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 else
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 /* second or fourth subframe */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 {
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 test (); test ();
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 /* if bfi == 0 decode pitch */
190
f387ee919f2c libgsmefr/dec_lag6.c: perf opt
Mychaela Falconia <falcon@freecalypso.org>
parents: 65
diff changeset
98 if ((bfi == 0) && (index < 61))
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 {
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 /* i = (index+5)/6 - 1 */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 i = sub (mult (add (index, 5), 5462), 1);
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
102 T0 = add (i, *T0_min);
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 i = add (add (i, i), i);
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 *T0_frac = sub (sub (index, 3), add (i, i));
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 else
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 /* bfi == 1 OR index >= 61 */
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 {
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
109 T0 = st->old_T0;
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
110 *T0_frac = 0;
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 }
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113
65
cb080ec1817e libgsmefr: dec_lag6.c compiles
Mychaela Falconia <falcon@freecalypso.org>
parents: 53
diff changeset
114 st->old_T0 = T0;
53
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 return T0;
49dd1ac8e75b libgsmefr: import most *.c files from ETSI source
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 }