annotate libgsmfr2/long_term.c @ 478:936a08cc73ce

doc/AMR-library-API: describe the decoder
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 19 May 2024 21:32:31 +0000
parents 65d3304502bd
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
267
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * This C source file has been adapted from TU-Berlin libgsm source,
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * original notice follows:
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 *
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <stdint.h>
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <assert.h>
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include "tw_gsmfr.h"
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include "typedef.h"
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include "ed_state.h"
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include "ed_internal.h"
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 /*
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 /*
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 * This module computes the LTP gain (bc) and the LTP lag (Nc)
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 * for the long term analysis filter. This is done by calculating a
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 * maximum of the cross-correlation function between the current
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 * sub-segment short term residual signal d[0..39] (output of
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 * the short term analysis filter; for simplification the index
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 * of this array begins at 0 and ends at 39 for each sub-segment of the
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 * RPE-LTP analysis) and the previous reconstructed short term
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 * performed to avoid overflow.
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 static void Calculation_of_the_LTP_parameters (
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 register word * d, /* [0..39] IN */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 register word * dp, /* [-120..-1] IN */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 word * bc_out, /* OUT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 word * Nc_out /* OUT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 )
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 register int k, lambda;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 word Nc, bc;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 word wt[40];
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 longword L_max, L_power;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 word R, S, dmax, scal;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 register word temp;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 /* Search of the optimum scaling of d[0..39].
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 dmax = 0;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 for (k = 0; k <= 39; k++) {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 temp = d[k];
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 temp = GSM_ABS( temp );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 if (temp > dmax) dmax = temp;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 temp = 0;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 if (dmax == 0) scal = 0;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 else {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 assert(dmax > 0);
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 temp = gsm_norm( (longword)dmax << 16 );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 if (temp > 6) scal = 0;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 else scal = 6 - temp;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 assert(scal >= 0);
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 /* Initialization of a working array wt
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 /* Search for the maximum cross-correlation and coding of the LTP lag
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 L_max = 0;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 Nc = 40; /* index for the maximum cross-correlation */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 for (lambda = 40; lambda <= 120; lambda++) {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 # undef STEP
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 # define STEP(k) (longword)wt[k] * dp[k - lambda]
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 register longword L_result;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 L_result = STEP(0) ; L_result += STEP(1) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 L_result += STEP(2) ; L_result += STEP(3) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 L_result += STEP(4) ; L_result += STEP(5) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 L_result += STEP(6) ; L_result += STEP(7) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 L_result += STEP(8) ; L_result += STEP(9) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 L_result += STEP(10) ; L_result += STEP(11) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 L_result += STEP(12) ; L_result += STEP(13) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 L_result += STEP(14) ; L_result += STEP(15) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 L_result += STEP(16) ; L_result += STEP(17) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 L_result += STEP(18) ; L_result += STEP(19) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 L_result += STEP(20) ; L_result += STEP(21) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 L_result += STEP(22) ; L_result += STEP(23) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 L_result += STEP(24) ; L_result += STEP(25) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 L_result += STEP(26) ; L_result += STEP(27) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 L_result += STEP(28) ; L_result += STEP(29) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 L_result += STEP(30) ; L_result += STEP(31) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 L_result += STEP(32) ; L_result += STEP(33) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 L_result += STEP(34) ; L_result += STEP(35) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 L_result += STEP(36) ; L_result += STEP(37) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 L_result += STEP(38) ; L_result += STEP(39) ;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 if (L_result > L_max) {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 Nc = lambda;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 L_max = L_result;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 *Nc_out = Nc;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 L_max <<= 1;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 /* Rescaling of L_max
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 assert(scal <= 100 && scal >= -100);
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
123 L_max = L_max >> (6 - scal); /* sub(6, scal) */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
124
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
125 assert( Nc <= 120 && Nc >= 40);
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
126
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
127 /* Compute the power of the reconstructed short term residual
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
128 * signal dp[..]
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
129 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
130 L_power = 0;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
131 for (k = 0; k <= 39; k++) {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
132
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
133 register longword L_temp;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
134
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
135 L_temp = SASR( dp[k - Nc], 3 );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
136 L_power += L_temp * L_temp;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
137 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
138 L_power <<= 1; /* from L_MULT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
139
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
140 /* Normalization of L_max and L_power
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
141 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
142
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
143 if (L_max <= 0) {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
144 *bc_out = 0;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
145 return;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
146 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
147 if (L_max >= L_power) {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
148 *bc_out = 3;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
149 return;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
150 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
151
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
152 temp = gsm_norm( L_power );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
153
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
154 R = SASR( L_max << temp, 16 );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
155 S = SASR( L_power << temp, 16 );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
156
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
157 /* Coding of the LTP gain
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
158 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
159
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
160 /* Table 4.3a must be used to obtain the level DLB[i] for the
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
161 * quantization of the LTP gain b to get the coded version bc.
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
162 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
163 for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
164 *bc_out = bc;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
165 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
166
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
167 /* 4.2.12 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
168
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
169 static void Long_term_analysis_filtering (
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
170 word bc, /* IN */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
171 word Nc, /* IN */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
172 register word * dp, /* previous d [-120..-1] IN */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
173 register word * d, /* d [0..39] IN */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
174 register word * dpp, /* estimate [0..39] OUT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
175 register word * e /* long term res. signal [0..39] OUT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
176 )
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
177 /*
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
178 * In this part, we have to decode the bc parameter to compute
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
179 * the samples of the estimate dpp[0..39]. The decoding of bc needs the
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
180 * use of table 4.3b. The long term residual signal e[0..39]
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
181 * is then calculated to be fed to the RPE encoding section.
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
182 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
183 {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
184 register int k;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
185 register longword ltmp;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
186
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
187 # undef STEP
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
188 # define STEP(BP) \
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
189 for (k = 0; k <= 39; k++) { \
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
190 dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
191 e[k] = GSM_SUB( d[k], dpp[k] ); \
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
192 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
193
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
194 switch (bc) {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
195 case 0: STEP( 3277 ); break;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
196 case 1: STEP( 11469 ); break;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
197 case 2: STEP( 21299 ); break;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
198 case 3: STEP( 32767 ); break;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
199 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
200 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
201
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
202 void Gsm_Long_Term_Predictor ( /* 4x for 160 samples */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
203 struct gsmfr_0610_state * S,
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
204
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
205 word * d, /* [0..39] residual signal IN */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
206 word * dp, /* [-120..-1] d' IN */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
207
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
208 word * e, /* [0..39] OUT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
209 word * dpp, /* [0..39] OUT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
210 word * Nc, /* correlation lag OUT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
211 word * bc /* gain factor OUT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
212 )
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
213 {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
214 assert( d ); assert( dp ); assert( e );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
215 assert( dpp); assert( Nc ); assert( bc );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
216
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
217 Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
218 Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
219 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
220
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
221 /* 4.3.2 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
222 void Gsm_Long_Term_Synthesis_Filtering (
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
223 struct gsmfr_0610_state * S,
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
224
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
225 word Ncr,
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
226 word bcr,
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
227 register word * erp, /* [0..39] IN */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
228 register word * drp /* [-120..-1] IN, [-120..40] OUT */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
229 )
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
230 /*
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
231 * This procedure uses the bcr and Ncr parameter to realize the
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
232 * long term synthesis filtering. The decoding of bcr needs
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
233 * table 4.3b.
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
234 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
235 {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
236 register longword ltmp; /* for ADD */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
237 register int k;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
238 word brp, drpp, Nr;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
239
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
240 /* Check the limits of Nr.
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
241 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
242 Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
243 S->nrp = Nr;
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
244 assert(Nr >= 40 && Nr <= 120);
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
245
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
246 /* Decoding of the LTP gain bcr
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
247 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
248 brp = gsm_QLB[ bcr ];
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
249
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
250 /* Computation of the reconstructed short term residual
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
251 * signal drp[0..39]
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
252 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
253 assert(brp != MIN_WORD);
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
254
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
255 for (k = 0; k <= 39; k++) {
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
256 drpp = GSM_MULT_R( brp, drp[ k - Nr ] );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
257 drp[k] = GSM_ADD( erp[k], drpp );
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
258 }
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
259
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
260 /*
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
261 * Update of the reconstructed short term residual signal
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
262 * drp[ -1..-120 ]
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
263 */
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
264
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
265 for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ];
65d3304502bd libgsmfr2: integrate long_term.c from libgsm
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
266 }