xref: /aosp_15_r20/external/libxaac/encoder/iusace_enc_fac.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2023 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 
21 #include <string.h>
22 #include "ixheaac_type_def.h"
23 #include "ixheaace_adjust_threshold_data.h"
24 #include "iusace_bitbuffer.h"
25 
26 /* DRC */
27 #include "impd_drc_common_enc.h"
28 #include "impd_drc_uni_drc.h"
29 #include "impd_drc_tables.h"
30 #include "impd_drc_api.h"
31 #include "impd_drc_uni_drc_eq.h"
32 #include "impd_drc_uni_drc_filter_bank.h"
33 #include "impd_drc_gain_enc.h"
34 #include "impd_drc_struct_def.h"
35 
36 #include "iusace_cnst.h"
37 #include "iusace_tns_usac.h"
38 #include "iusace_psy_mod.h"
39 #include "iusace_config.h"
40 #include "iusace_arith_enc.h"
41 #include "iusace_block_switch_const.h"
42 #include "iusace_block_switch_struct_def.h"
43 #include "iusace_fd_qc_util.h"
44 #include "iusace_fd_quant.h"
45 #include "iusace_ms.h"
46 #include "iusace_signal_classifier.h"
47 #include "ixheaace_sbr_header.h"
48 #include "ixheaace_config.h"
49 #include "ixheaace_asc_write.h"
50 #include "iusace_main.h"
51 #include "iusace_write_bitstream.h"
52 #include "iusace_func_prototypes.h"
53 #include "iusace_avq_enc.h"
54 #include "iusace_lpd_rom.h"
55 
iusace_unary_code(WORD32 idx,WORD16 * ptr_bit_buf)56 static WORD32 iusace_unary_code(WORD32 idx, WORD16 *ptr_bit_buf) {
57   WORD32 num_bits;
58 
59   num_bits = 1;
60 
61   idx -= 1;
62   while (idx-- > 0) {
63     *ptr_bit_buf++ = 1;
64     num_bits++;
65   }
66 
67   *ptr_bit_buf = 0;
68 
69   return (num_bits);
70 }
71 
iusace_get_nk_mode(WORD32 mode_lpc,ia_bit_buf_struct * pstr_it_bit_buff,WORD32 * nk_mode,WORD32 lpc_set)72 static VOID iusace_get_nk_mode(WORD32 mode_lpc, ia_bit_buf_struct *pstr_it_bit_buff,
73                                WORD32 *nk_mode, WORD32 lpc_set) {
74   switch (lpc_set) {
75     case 4:
76       break;
77     case 0:
78     case 2:
79       *nk_mode = 3;
80       iusace_write_bits_buf(pstr_it_bit_buff, mode_lpc, 1);
81       break;
82     case 1:
83       *nk_mode = mode_lpc;
84       if (mode_lpc == 2) {
85         iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
86       } else if (mode_lpc == 1) {
87         iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
88         iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
89       } else if (mode_lpc == 0) {
90         iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
91         iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
92       }
93       break;
94     case 3:
95       if (mode_lpc == 0) {
96         *nk_mode = 0;
97         iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
98         iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
99       } else if (mode_lpc == 1) {
100         *nk_mode = 1;
101         iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
102       } else if (mode_lpc == 2) {
103         *nk_mode = 2;
104         iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
105         iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
106         iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
107       } else {
108         *nk_mode = 2;
109         iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
110         iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
111         iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
112       }
113       break;
114   }
115   return;
116 }
117 
iusace_write_qn_data(WORD32 * qn,ia_bit_buf_struct * pstr_it_bit_buff,WORD32 nk_mode,WORD32 num_frames)118 static VOID iusace_write_qn_data(WORD32 *qn, ia_bit_buf_struct *pstr_it_bit_buff, WORD32 nk_mode,
119                                  WORD32 num_frames) {
120   WORD32 k, i;
121   switch (nk_mode) {
122     case 1:
123       for (k = 0; k < 2; k++) {
124         for (i = 0; i < qn[k] - 1; i++) {
125           iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
126         }
127         iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
128       }
129       break;
130     case 0:
131     case 2:
132     case 3:
133       for (k = 0; k < 2; k++) {
134         WORD32 qn1 = qn[k] - 2;
135         if (qn1 < 0 || qn1 > 3) {
136           qn1 = 3;
137         }
138         iusace_write_bits_buf(pstr_it_bit_buff, qn1, 2);
139       }
140       if ((nk_mode == 2) && num_frames != 2) {
141         for (k = 0; k < 2; k++) {
142           if (qn[k] > 4) {
143             for (i = 0; i < qn[k] - 4; i++) {
144               iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
145             }
146             iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
147           }
148           if (qn[k] == 0) {
149             iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
150           }
151         }
152       } else {
153         for (k = 0; k < 2; k++) {
154           if (qn[k] == 5) {
155             iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
156           } else if (qn[k] == 6) {
157             iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
158             iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
159           } else if (qn[k] == 0) {
160             iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
161             iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
162             iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
163           } else {
164             WORD32 qn_ext = qn[k] - 4;
165             if (qn_ext > 0) {
166               for (i = 0; i < qn_ext; i++) {
167                 iusace_write_bits_buf(pstr_it_bit_buff, 1, 1);
168               }
169               iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
170             }
171           }
172         }
173       }
174       break;
175   }
176   return;
177 }
178 
iusace_write_cb_indices(WORD32 * qn,WORD32 * ptr_params,WORD32 * idx,ia_bit_buf_struct * pstr_it_bit_buff,WORD32 nk_mode,WORD32 num_frames)179 static VOID iusace_write_cb_indices(WORD32 *qn, WORD32 *ptr_params, WORD32 *idx,
180                                     ia_bit_buf_struct *pstr_it_bit_buff, WORD32 nk_mode,
181                                     WORD32 num_frames) {
182   WORD32 k;
183   WORD32 j = *idx;
184 
185   iusace_write_qn_data(qn, pstr_it_bit_buff, nk_mode, num_frames);
186 
187   for (k = 0; k < 2; k++) {
188     if (qn[k] > 0) {
189       WORD32 n, nk, i;
190       if (qn[k] > 4) {
191         nk = (qn[k] - 3) >> 1;
192         n = qn[k] - nk * 2;
193       } else {
194         nk = 0;
195         n = qn[k];
196       }
197 
198       iusace_write_bits_buf(pstr_it_bit_buff, ptr_params[j++], (UWORD8)(4 * n));
199 
200       for (i = 0; i < 8; i++) {
201         iusace_write_bits_buf(pstr_it_bit_buff, ptr_params[j++], (UWORD8)nk);
202       }
203     }
204   }
205 
206   *idx = j;
207 
208   return;
209 }
210 
iusace_write_lpc_data(ia_bit_buf_struct * pstr_it_bit_buff,WORD32 * param_lpc,WORD32 first_lpd_flag,WORD32 * mod,WORD32 num_frames)211 static VOID iusace_write_lpc_data(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 *param_lpc,
212                                   WORD32 first_lpd_flag, WORD32 *mod, WORD32 num_frames) {
213   WORD32 nk_mode = 0;
214   WORD32 j = 0, k;
215   WORD32 mode_lpc = 0;
216   WORD32 qn[2] = {0};
217 
218   iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 4);
219 
220   iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
221 
222   for (k = 0; k < 2; k++) {
223     qn[k] = param_lpc[j++];
224   }
225 
226   iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
227 
228   if (first_lpd_flag) {
229     mode_lpc = param_lpc[j++];
230     iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 0);
231 
232     if (mode_lpc == 0) {
233       iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
234     }
235 
236     for (k = 0; k < 2; k++) {
237       qn[k] = param_lpc[j++];
238     }
239 
240     iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
241   }
242 
243   mode_lpc = param_lpc[j++];
244 
245   if (num_frames == 4 && mod[0] < 3) {
246     iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 2);
247 
248     if (mode_lpc == 0) {
249       iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
250     }
251 
252     for (k = 0; k < 2; k++) {
253       qn[k] = param_lpc[j++];
254     }
255 
256     iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
257   }
258   mode_lpc = param_lpc[j++];
259   if (mod[0] < 2) {
260     iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 1);
261 
262     if (mode_lpc != 1) {
263       if (mode_lpc == 0) {
264         iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
265       }
266 
267       for (k = 0; k < 2; k++) {
268         qn[k] = param_lpc[j++];
269       }
270 
271       iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
272     }
273   } else if (mode_lpc != 1) {
274     if (mode_lpc == 0) {
275       j++;
276     }
277     for (k = 0; k < 2; k++) {
278       qn[k] = param_lpc[j++];
279     }
280     j += ((qn[0] > 0) ? 9 : 0) + ((qn[1] > 0) ? 9 : 0);
281   }
282 
283   mode_lpc = param_lpc[j++];
284   if (num_frames != 2 && mod[2] < 2) {
285     iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 3);
286     if (mode_lpc == 0) {
287       iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8);
288     }
289 
290     for (k = 0; k < 2; k++) {
291       qn[k] = param_lpc[j++];
292     }
293     iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames);
294   }
295   return;
296 }
297 
iusace_encode_fac_params(WORD32 * mod,WORD32 * n_param_tcx,ia_usac_data_struct * usac_data,WORD32 const usac_independency_flag,ia_bit_buf_struct * pstr_it_bit_buff,WORD32 ch_idx)298 VOID iusace_encode_fac_params(WORD32 *mod, WORD32 *n_param_tcx, ia_usac_data_struct *usac_data,
299                               WORD32 const usac_independency_flag,
300                               ia_bit_buf_struct *pstr_it_bit_buff, WORD32 ch_idx) {
301   WORD32 *total_nbbits = &usac_data->total_nbbits[ch_idx];
302   ia_usac_td_encoder_struct *pstr_td = usac_data->td_encoder[ch_idx];
303   WORD32 codec_mode = pstr_td->acelp_core_mode;
304   WORD16 *bit_buf = usac_data->td_serial_out[ch_idx];
305   WORD32 is_bass_post_filter = 1;
306   WORD32 first_lpd_flag = (usac_data->core_mode_prev[ch_idx] == CORE_MODE_FD);
307   WORD32 *param_lpc = usac_data->param_buf + (NUM_FRAMES * MAX_NUM_TCX_PRM_PER_DIV);
308   WORD32 *param = usac_data->param_buf;
309   WORD32 j, k, n, sfr, lpd_mode, num_bits, sq_bits, *prm;
310   WORD16 first_tcx_flag = 1;
311   WORD32 nbits_fac, nb_bits_lpc;
312   WORD32 core_mode_last = (first_lpd_flag) ? 0 : 1;
313   WORD32 fac_data_present;
314   WORD32 num_frames = NUM_FRAMES;
315   WORD16 *ptr_bit_buf = bit_buf;
316 
317   pstr_td->num_bits_per_supfrm = 0;
318   *total_nbbits = 0;
319 
320   iusace_write_bits_buf(pstr_it_bit_buff, pstr_td->acelp_core_mode, 3);
321 
322   if (mod[0] == 3) {
323     lpd_mode = 25;
324   } else if ((mod[0] == 2) && (mod[2] == 2)) {
325     lpd_mode = 24;
326   } else {
327     if (mod[0] == 2) {
328       lpd_mode = 16 + mod[2] + 2 * mod[3];
329     } else if (mod[2] == 2) {
330       lpd_mode = 20 + mod[0] + 2 * mod[1];
331     } else {
332       lpd_mode = mod[0] + 2 * mod[1] + 4 * mod[2] + 8 * mod[3];
333     }
334   }
335   iusace_write_bits_buf(pstr_it_bit_buff, lpd_mode, 5);
336   pstr_td->num_bits_per_supfrm = 5;
337   *total_nbbits += 5;
338 
339   iusace_write_bits_buf(pstr_it_bit_buff, is_bass_post_filter, 1);
340   *total_nbbits += 1;
341 
342   iusace_write_bits_buf(pstr_it_bit_buff, core_mode_last, 1);
343   *total_nbbits += 1;
344 
345   if (((mod[0] == 0) && (mod[-1] != 0)) || ((mod[0] > 0) && (mod[-1] == 0))) {
346     fac_data_present = 1;
347   } else {
348     fac_data_present = 0;
349   }
350 
351   iusace_write_bits_buf(pstr_it_bit_buff, fac_data_present, 1);
352   *total_nbbits += 1;
353 
354   num_bits = (iusace_acelp_core_numbits_1024[codec_mode] / 4) - 2;
355 
356   k = 0;
357   while (k < num_frames) {
358     lpd_mode = mod[k];
359     prm = param + (k * MAX_NUM_TCX_PRM_PER_DIV);
360     j = 0;
361 
362     if (((mod[k - 1] == 0) && (mod[k] > 0)) || ((mod[k - 1] > 0) && (mod[k] == 0))) {
363       nbits_fac = iusace_fd_encode_fac(&prm[j], ptr_bit_buf, (pstr_td->len_subfrm) / 2);
364       j += (pstr_td->len_subfrm) / 2;
365       *total_nbbits += nbits_fac;
366       for (WORD32 i = 0; i < nbits_fac; i++) {
367         iusace_write_bits_buf(pstr_it_bit_buff, ptr_bit_buf[i], 1);
368       }
369     }
370 
371     if (lpd_mode == 0) {
372       iusace_write_bits_buf(pstr_it_bit_buff, prm[j++], 2);
373 
374       for (sfr = 0; sfr < (pstr_td->num_subfrm); sfr++) {
375         n = 6;
376         if ((sfr == 0) || (((pstr_td->len_subfrm) == 256) && (sfr == 2))) n = 9;
377         iusace_write_bits_buf(pstr_it_bit_buff, prm[j], (UWORD8)n);
378         j++;
379         iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 1);
380         j++;
381         if (codec_mode == ACELP_CORE_MODE_9k6) {
382           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
383           j++;
384           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
385           j++;
386           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
387           j++;
388           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
389           j++;
390         } else if (codec_mode == ACELP_CORE_MODE_11k2) {
391           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
392           j++;
393           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
394           j++;
395           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
396           j++;
397           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5);
398           j++;
399         } else if (codec_mode == ACELP_CORE_MODE_12k8) {
400           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
401           j++;
402           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
403           j++;
404           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
405           j++;
406           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
407           j++;
408         } else if (codec_mode == ACELP_CORE_MODE_14k4) {
409           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
410           j++;
411           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
412           j++;
413           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
414           j++;
415           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9);
416           j++;
417         } else if (codec_mode == ACELP_CORE_MODE_16k) {
418           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
419           j++;
420           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
421           j++;
422           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
423           j++;
424           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13);
425           j++;
426         } else if (codec_mode == ACELP_CORE_MODE_18k4) {
427           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2);
428           j++;
429           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2);
430           j++;
431           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2);
432           j++;
433           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2);
434           j++;
435           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14);
436           j++;
437           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14);
438           j++;
439           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14);
440           j++;
441           iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14);
442           j++;
443         }
444         iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 7);
445         j++;
446       }
447       *total_nbbits += (num_bits - NBITS_LPC);
448       pstr_td->num_bits_per_supfrm += (num_bits - NBITS_LPC);
449       k++;
450     } else {
451       iusace_write_bits_buf(pstr_it_bit_buff, prm[j++], 3);
452       *total_nbbits += 3;
453       pstr_td->num_bits_per_supfrm += 3;
454       iusace_write_bits_buf(pstr_it_bit_buff, prm[j++], 7);
455       *total_nbbits += 7;
456       pstr_td->num_bits_per_supfrm += 7;
457 
458       if (first_tcx_flag) {
459         first_tcx_flag = 0;
460         if (usac_independency_flag) {
461           pstr_td->arith_reset_flag = 1;
462           memset(pstr_td->c_pres, 0, 516 * sizeof(WORD32));
463           memset(pstr_td->c_prev, 0, 516 * sizeof(WORD32));
464         } else {
465           if (pstr_td->arith_reset_flag) {
466             memset(pstr_td->c_pres, 0, 516 * sizeof(WORD32));
467             memset(pstr_td->c_prev, 0, 516 * sizeof(WORD32));
468           }
469           iusace_write_bits_buf(pstr_it_bit_buff, pstr_td->arith_reset_flag, 1);
470           *total_nbbits += 1;
471           pstr_td->num_bits_per_supfrm += 1;
472         }
473       }
474 
475       sq_bits = iusace_tcx_coding(pstr_it_bit_buff, n_param_tcx[k], pstr_td->len_frame, prm + j,
476                                   pstr_td->c_pres, pstr_td->c_prev);
477 
478       *total_nbbits += sq_bits;
479       pstr_td->num_bits_per_supfrm += sq_bits;
480 
481       k += (1 << (lpd_mode - 1));
482     }
483   }
484 
485   nb_bits_lpc = pstr_it_bit_buff->cnt_bits;
486 
487   iusace_write_lpc_data(pstr_it_bit_buff, param_lpc, first_lpd_flag, mod, num_frames);
488 
489   nb_bits_lpc = pstr_it_bit_buff->cnt_bits - nb_bits_lpc;
490   *total_nbbits += nb_bits_lpc;
491   pstr_td->num_bits_per_supfrm += nb_bits_lpc;
492 
493   if ((core_mode_last == 0) && (fac_data_present == 1)) {
494     WORD32 short_fac_flag = (mod[-1] == -2) ? 1 : 0;
495     iusace_write_bits_buf(pstr_it_bit_buff, short_fac_flag, 1);
496     *total_nbbits += 1;
497   }
498 
499   return;
500 }
501 
iusace_fd_encode_fac(WORD32 * prm,WORD16 * ptr_bit_buf,WORD32 fac_length)502 WORD32 iusace_fd_encode_fac(WORD32 *prm, WORD16 *ptr_bit_buf, WORD32 fac_length) {
503   WORD32 i, j, n, nb, qn, kv[8], nk, fac_bits;
504   WORD32 I;
505 
506   fac_bits = 0;
507 
508   for (i = 0; i < fac_length; i += 8) {
509     iusace_apply_voronoi_ext(&prm[i], &qn, &I, kv);
510 
511     nb = iusace_unary_code(qn, ptr_bit_buf);
512     ptr_bit_buf += nb;
513 
514     fac_bits += nb;
515 
516     nk = 0;
517     n = qn;
518     if (qn > 4) {
519       nk = (qn - 3) >> 1;
520       n = qn - nk * 2;
521     }
522 
523     if (qn != 0) {
524       iusace_write_bits2buf(I, 4 * n, ptr_bit_buf);
525       ptr_bit_buf += 4 * n;
526     }
527     if (qn > 4) {
528       for (j = 0; j < 8; j++) {
529         iusace_write_bits2buf(kv[j], nk, ptr_bit_buf);
530         ptr_bit_buf += nk;
531       }
532     }
533     fac_bits += 4 * qn;
534   }
535 
536   return fac_bits;
537 }
538