Line data Source code
1 : /******************************************************************************
2 : * ETSI TS 103 634 V1.5.1 *
3 : * Low Complexity Communication Codec Plus (LC3plus) *
4 : * *
5 : * Copyright licence is solely granted through ETSI Intellectual Property *
6 : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
7 : * estoppel or otherwise. *
8 : ******************************************************************************/
9 :
10 : #include "functions.h"
11 :
12 : static Word32 ac_enc_mux_st2VQ_cws( /* o: max 25 bits total codeword */
13 : const Word32 L_szA, /* i: max 22 bits */
14 : const Word32 L_szB, /* i: max 4 bits */
15 : const Word32 L_cwA, const Word32 L_cwB);
16 :
17 0 : void processEncoderEntropy(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 targetBytes,
18 : Word16 L_spec, Word16 BW_cutoff_bits, Word16 tns_numfilters,
19 : Word16 lsbMode, Word16 lastnz, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx,
20 : Word16 BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx, Word16 bfi_ext, Word16 fs_idx)
21 : {
22 : Word16 tmp;
23 : Word32 L_tmp;
24 : Word16 submode_LSB, submode_MSB, gain_MSBs;
25 : Word32 L_gain_LSB;
26 : Counter n;
27 : UWord8 *ptr;
28 :
29 0 : Word16 lastnzTrigger[5] = {63, 127, 127, 255, 255};
30 :
31 : #ifdef DYNMEM_COUNT
32 : struct _dynmem
33 : {
34 : Word16 tmp;
35 : Word32 L_tmp;
36 : Word16 submode_LSB, submode_MSB, gain_MSBs;
37 : Word32 L_gain_LSB;
38 : Counter n;
39 : UWord8 *ptr;
40 : Word16 lastnzTrigger[5];
41 : };
42 : Dyn_Mem_In("processEncoderEntropy", sizeof(struct _dynmem));
43 : #endif
44 :
45 : /* Init */
46 0 : *bp_side = shr_pos(sub(nbbits, 1), 3);
47 0 : *mask_side = shl(1, sub(8, sub(nbbits, shl_pos(*bp_side, 3))));
48 0 : ptr = bytes;
49 :
50 0 : basop_memset(bytes, 0, targetBytes * sizeof(*bytes));
51 :
52 : /* Cutoff-detection */
53 0 : IF (BW_cutoff_bits > 0)
54 : {
55 0 : write_indice_backward(ptr, bp_side, mask_side, BW_cutoff_idx, BW_cutoff_bits);
56 : }
57 :
58 : /* Encode last non-zero tuple */
59 0 : tmp = sub(14, norm_s(negate(L_spec)));
60 :
61 0 : IF (sub(bfi_ext, 1) == 0)
62 : {
63 0 : write_indice_backward(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], tmp);
64 : }
65 : ELSE
66 : {
67 0 : write_indice_backward(ptr, bp_side, mask_side, sub(shr_pos(lastnz, 1), 1), tmp);
68 : }
69 :
70 : /* Mode bit */
71 0 : write_bit_backward(ptr, bp_side, mask_side, lsbMode);
72 :
73 : /* Encode global-gain */
74 0 : write_indice_backward(ptr, bp_side, mask_side, gg_idx, 8);
75 :
76 : /* TNS on/off flag */
77 0 : FOR (n = 0; n < tns_numfilters; n++)
78 : {
79 0 : write_bit_backward(ptr, bp_side, mask_side, s_min(tns_order[n], 1));
80 : }
81 :
82 : /* LTPF on/off*/
83 0 : write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[0], 1);
84 :
85 : /* Encode SCF VQ parameters - 1st stage (10 bits) */
86 0 : write_indice_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[0]), 5); /* stage1 LF 5 bits */
87 0 : write_indice_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[1]), 5); /* stage1 HF 5 bits */
88 :
89 : /* Encode SCF VQ parameters - 2nd stage side-info (3-4 bits) */
90 0 : submode_MSB = shr_pos(extract_l(L_scf_idx[2]), 1); /* explicit tx */
91 0 : write_bit_backward(ptr, bp_side, mask_side, submode_MSB); /* submode MSB 1 explicit bit */
92 0 : submode_LSB = s_and(extract_l(L_scf_idx[2]), 0x1); /* for joint coding with shapeCw */
93 0 : gain_MSBs = extract_l(L_scf_idx[3]); /* all gain bits */
94 0 : L_gain_LSB = L_and(L_scf_idx[3], 0x1L);
95 0 : gain_MSBs = shr(gain_MSBs, sns_gainLSBbits[L_scf_idx[2]]);
96 :
97 0 : ASSERT(gain_MSBs >= 0 && gain_MSBs < (1 << sns_gainMSBbits[L_scf_idx[2]])); /* ASSERT max 2 MSB(s) in gain bits */
98 :
99 0 : write_indice_backward(ptr, bp_side, mask_side, gain_MSBs,
100 0 : sns_gainMSBbits[L_scf_idx[2]]); /* adjgain or MSBs of adjGains 1-2 bits */
101 0 : write_bit_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[4])); /* shape LS 1 bit */
102 :
103 : /* Encode SCF VQ parameters - 2nd stage data (24-25 bits) */
104 0 : IF (submode_MSB == 0)
105 : { /* regular,regular_lf*/
106 0 : ASSERT(submode_MSB == 0);
107 :
108 0 : L_tmp = L_add(L_gain_LSB, 0); /* gain-LSB 0,1 for regular_lf, offset is 0 */
109 0 : if (submode_LSB == 0)
110 : {
111 0 : L_tmp = L_add(L_scf_idx[6],
112 0 : sns_MPVQ_Sz[1][1]); /* shape B pos offset is 2 , upshifted two positions , 0..11 -> 2..13 */
113 : }
114 : /* regular mode A,B indexes multiplexed, total 24.x bits MPVQ codeword section A + codeword for section B */
115 0 : L_tmp = ac_enc_mux_st2VQ_cws(sns_MPVQ_Sz[0][0], /* max 21.3 bits*/
116 0 : UL_addNsD(sns_MPVQ_Sz[0][1], sns_MPVQ_Sz[1][1]), /* max log2(14) bits */
117 0 : L_scf_idx[5] /* shapeA */, L_tmp /* shapeB joint with adjGainLSB */);
118 : /* regular mode mode shape index total 1+23.9999 bits MPVQ codeword */
119 0 : ASSERT(L_tmp < (1L << 25));
120 0 : write_indice_backward(ptr, bp_side, mask_side, extract_l(L_tmp), 13); /* multiplex 13 bits */
121 0 : write_indice_backward(ptr, bp_side, mask_side, extract_l(L_shr_pos(L_tmp, 13)), 12); /* multiplex 12 bits */
122 : }
123 : ELSE
124 : { /* outlier near, outlier far */
125 0 : ASSERT(submode_MSB == 1);
126 0 : L_tmp = L_scf_idx[5]; move32(); /* outlier near section assumed */
127 0 : if (submode_LSB != 0)
128 : { /* outl_far */
129 0 : L_tmp = L_add(L_shl_pos(L_tmp, 1), L_gain_LSB); /* add lsb bit of Gain */
130 0 : L_tmp = L_add(L_tmp, sns_MPVQ_Sz[2][0]); /* outlier far section offset added */
131 : }
132 :
133 0 : ASSERT(L_tmp < (1L << 24));
134 : /* outlier mode shape index total 23.8536 ( + ~.14 ) bits as MPVQ codeword */
135 0 : write_indice_backward(ptr, bp_side, mask_side, extract_l(L_tmp), 12); /* multiplex 12 bits LSB*/
136 0 : write_indice_backward(ptr, bp_side, mask_side, extract_l(L_shr(L_tmp, 12)), 12); /* multiplex 12 bits MSBs */
137 : }
138 :
139 : /* LTPF data */
140 0 : IF (ltpf_idx[0] != 0)
141 : {
142 0 : write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[1], 1);
143 0 : write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[2], 9);
144 : }
145 :
146 : /* Encoder noise-fac */
147 0 : write_indice_backward(ptr, bp_side, mask_side, fac_ns_idx, 3);
148 :
149 : #ifdef DYNMEM_COUNT
150 : Dyn_Mem_Out();
151 : #endif
152 0 : }
153 :
154 : static __forceinline Word32
155 0 : ac_enc_mux_st2VQ_cws( /* o: max 25 bits total codeword */
156 : const Word32 L_szA, /* i: max 22 bits */
157 : const Word32 L_szB, /* i: max 4 bits 0..13 */
158 : const Word32 L_cwA,
159 : const Word32 L_cwB) /* [0..13} corresponding to gains{0,1}, shapeB{0..11} or */
160 : {
161 :
162 : Word32 L_cwTx;
163 : /* L_cw_tx = L_cwB(21.z bits) * L_szA(3.y bits) + L_cwA(21.x bits)); */
164 0 : L_cwTx = (Word32)UL_Mpy_32_32(
165 : (UWord32)L_cwB, (UWord32)L_szA); /* non-fractional 16x32 -> 32 may possibly also be used if available */
166 0 : L_cwTx = L_add(L_cwTx, L_cwA);
167 :
168 0 : ASSERT((L_szA * L_szB) <= 1 << 25); /* multiplexing only allowed up to 25 bits (+ leading sign) */
169 0 : ASSERT(L_cwTx >= 0 && L_cwTx <= 0x01ffFFff); /* max 25 bits allowed */
170 : UNUSED(L_szB);
171 :
172 0 : return L_cwTx;
173 : }
|