Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "cnst.h"
7 : #include "options.h"
8 : #include "rom_com.h"
9 : #include "prot_fx.h"
10 : #include "basop_util.h"
11 :
12 : #ifndef swap
13 : #define swap( x, y, type ) \
14 : { \
15 : type u__p; \
16 : u__p = x; \
17 : x = y; \
18 : y = u__p; \
19 : }
20 : #endif
21 : /*---------------------------------------------------------------------*
22 : * midlsf_dec()
23 : *
24 : *
25 : *---------------------------------------------------------------------*/
26 1071 : void midlsf_dec(
27 : const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */
28 : const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */
29 : const Word16 idx, /* i: codebook index */
30 : Word16 qlsf[], /* o: decoded lsf coefficients (3Q12) */
31 : const Word16 coder_type,
32 : Word16 *mid_lsf_int, /*Q0*/
33 : const Word16 prev_bfi,
34 : const Word16 safety_net )
35 : {
36 1071 : const Word16 *ratio = NULL;
37 : Word16 j;
38 : Word32 L_tmp;
39 1071 : Word16 bad_spacing = 0;
40 1071 : move16();
41 :
42 : /* Select codebook */
43 1071 : IF( EQ_16( coder_type, UNVOICED ) )
44 : {
45 57 : ratio = tbl_mid_unv_wb_5b_fx;
46 : }
47 : ELSE
48 : {
49 1014 : ratio = tbl_mid_gen_wb_5b_fx;
50 : }
51 18207 : FOR( j = 0; j < M; j++ )
52 : {
53 17136 : L_tmp = L_mult( sub( 0x2000, ratio[idx * M + j] ), qlsf0[j] ); /*Q(x2.56+13+1)->Q(x2.56+14)*/
54 17136 : L_tmp = L_mac( L_tmp, ratio[idx * M + j], qlsf1[j] ); /*Q(x2.56+14)*/
55 17136 : qlsf[j] = round_fx( L_shl( L_tmp, 2 ) ); /*Q(x2.56)*/
56 17136 : move16();
57 : }
58 :
59 :
60 1071 : IF( mid_lsf_int != NULL ) /*at the decoder*/
61 : {
62 : /* check for incorrect LSF ordering */
63 337 : IF( EQ_16( *mid_lsf_int, 1 ) )
64 : {
65 0 : FOR( j = 1; j < M; j++ )
66 : {
67 0 : IF( LT_16( qlsf[j], qlsf[j - 1] ) )
68 : {
69 0 : bad_spacing = 1;
70 0 : move16();
71 0 : BREAK;
72 : }
73 : }
74 : }
75 : /* Redo mid-LSF interpolation with 0.4 in case of LSF instability */
76 337 : test();
77 337 : test();
78 337 : IF( prev_bfi || ( EQ_16( *mid_lsf_int, 1 ) && bad_spacing ) )
79 : {
80 0 : FOR( j = 0; j < M; j++ )
81 : {
82 : /* redo mid-LSF interpolation with 0.4 */
83 0 : qlsf[j] = add( mult_r( 13107, qlsf0[j] ), mult_r( 19661, qlsf1[j] ) ); /* Q15 +x2.56 -Q15 13107 = 0.4(Q15), 19661 = 0.6 (Q15)*/
84 0 : move16();
85 :
86 : /* ensure correct ordering of LSF indices */
87 0 : test();
88 0 : test();
89 0 : IF( j > 0 && LT_16( j, M ) && LT_16( qlsf[j], add( qlsf[j - 1], LSF_GAP_MID_FX ) ) )
90 : {
91 0 : qlsf[j] = add( qlsf[j - 1], LSF_GAP_MID_FX );
92 0 : move16();
93 : }
94 : }
95 : }
96 : ELSE
97 : {
98 : /* otherwise, use regular LSF spacing and ordering as in the encoder */
99 5729 : FOR( j = 0; j < M; j++ )
100 : {
101 5392 : test();
102 5392 : test();
103 5392 : IF( j > 0 && LT_16( j, M ) && LT_16( qlsf[j], add( qlsf[j - 1], LSF_GAP_MID_FX ) ) )
104 : {
105 34 : qlsf[j] = add( qlsf[j - 1], LSF_GAP_MID_FX );
106 34 : move16();
107 : }
108 : }
109 : }
110 337 : if ( prev_bfi )
111 : {
112 : /* continue redoing mid-LSF interpolation with 0.4 in order not to propagate the error */
113 0 : *mid_lsf_int = 1;
114 0 : move16();
115 : }
116 337 : if ( safety_net )
117 : {
118 : /* safety-net encountered -> stop redoing mid-LSF interpolation with 0.4 */
119 0 : *mid_lsf_int = 0;
120 0 : move16();
121 : }
122 : }
123 : ELSE
124 : {
125 : /* use regular LSF spacing */
126 12478 : FOR( j = 0; j < M; j++ )
127 : {
128 11744 : test();
129 11744 : test();
130 11744 : IF( j > 0 && LT_16( j, M ) && LT_16( qlsf[j], add( qlsf[j - 1], LSF_GAP_MID_FX ) ) )
131 : {
132 69 : qlsf[j] = add( qlsf[j - 1], LSF_GAP_MID_FX );
133 69 : move16();
134 : }
135 : }
136 : }
137 :
138 1071 : return;
139 : }
140 31484 : Word16 lsf_ind_is_active(
141 : const Word16 lsf_q_ind[], /*(14Q1*1.28)*/
142 : const Word16 means[], /*(14Q1*1.28)*/
143 : const Word16 narrowband,
144 : const Word16 cdk )
145 : {
146 : Word16 lsf[2], min_distance;
147 :
148 31484 : lsf[0] = add( lsf_q_ind[0], means[0] );
149 31484 : move16();
150 31484 : lsf[1] = add( lsf_q_ind[1], means[1] );
151 31484 : move16();
152 :
153 31484 : min_distance = lsf[0];
154 31484 : move16();
155 31484 : min_distance = s_min( min_distance, sub( lsf[1], lsf[0] ) );
156 :
157 31484 : assert( narrowband == 0 || narrowband == 1 );
158 31484 : assert( cdk == 0 || cdk == 1 );
159 :
160 31484 : return sub( min_distance, min_distance_thr[narrowband][cdk] ) < 0;
161 : }
|