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 0 : void scale_signal24_fx(Word32 x[], /* i: time input signal */
13 : #ifdef ENABLE_HR_MODE
14 : Word32 x_scaled[],
15 : #else
16 : Word16 x_scaled[],
17 : #endif
18 : Word16 *x_exp,
19 : #ifdef ENABLE_HR_MODE
20 : Word32 mdct_mem[],
21 : #else
22 : Word16 mdct_mem[],
23 : #endif
24 : Word16 mdct_mem_len,
25 : Word16 resample_mem_in[], Word16 resample_mem_in_len, Word32 resample_mem_in50[],
26 : Word16 resample_mem_out[], Word16 resample_mem_out_len, Word32 mdct_mem32[], Word16 N,
27 : Word32 resamp_mem32[], Word16 mem_s12k8[], Word16 *resamp_scale)
28 : {
29 : Word16 i;
30 : Word16 s;
31 : Word16 scales[6];
32 :
33 : #ifdef DYNMEM_COUNT
34 : Dyn_Mem_In("scale_signal24_fx", sizeof(struct {
35 : Word16 i;
36 : Word16 s;
37 : Word16 scales[6];
38 : }));
39 : #endif
40 :
41 : /* Scale input for 24 bit case */
42 : /* assure 24 bit input */
43 0 : FOR (i = 0; i < N; i++)
44 : {
45 0 : IF (x[i] >= 0)
46 : {
47 0 : x[i] = L_and(x[i], 0x007fffff);
48 : }
49 : ELSE
50 : {
51 0 : x[i] = (Word32)L_or( (UWord32)x[i], 0xff800000);
52 : }
53 : }
54 :
55 : /* Find maximum exponent */
56 0 : scales[0] = sub(15 + 8, getScaleFactor32_0(x, N));
57 0 : scales[1] = sub(15 + 8, getScaleFactor32_0(mdct_mem32, mdct_mem_len));
58 0 : scales[2] = sub(15 + 8, getScaleFactor32_0(resamp_mem32, resample_mem_in_len));
59 0 : scales[3] = sub(sub(*resamp_scale, 2), getScaleFactor32_0(resample_mem_in50, 2));
60 0 : scales[4] = sub(sub(*resamp_scale, 2), getScaleFactor16_0(resample_mem_out, resample_mem_out_len));
61 0 : scales[5] = sub(sub(*resamp_scale, 2), getScaleFactor16_0(mem_s12k8, 3));
62 0 : *x_exp = 7; move16();
63 0 : FOR (i = 0; i < 6; i++)
64 : {
65 0 : *x_exp = s_max(*x_exp, scales[i]); move16();
66 : }
67 :
68 : /* Shift input buffers */
69 0 : s = sub(15 + 8, *x_exp);
70 0 : FOR (i = 0; i < N; i++)
71 : {
72 : #ifdef ENABLE_HR_MODE
73 0 : x_scaled[i] = L_shl(x[i], s);
74 : #else
75 : x_scaled[i] = round_fx_sat(L_shl(x[i], s));
76 : #endif
77 : }
78 :
79 0 : FOR (i = 0; i < mdct_mem_len; i++)
80 : {
81 : #ifdef ENABLE_HR_MODE
82 0 : mdct_mem[i] = L_shl(mdct_mem32[i], s);
83 : #else
84 : mdct_mem[i] = round_fx_sat(L_shl(mdct_mem32[i], s));
85 : #endif
86 : }
87 :
88 0 : FOR (i = 0; i < resample_mem_in_len; i++)
89 : {
90 0 : resample_mem_in[i] = round_fx_sat(L_shl(resamp_mem32[i], s));
91 : }
92 :
93 : /* Adjust resampler filter and output buffers */
94 0 : s = sub(sub(*resamp_scale, 2), *x_exp);
95 0 : *resamp_scale = add(*x_exp, 2);
96 :
97 0 : IF (s)
98 : {
99 0 : FOR (i = 0; i < 2; i++)
100 : {
101 0 : resample_mem_in50[i] = L_shl(resample_mem_in50[i], s);
102 : }
103 0 : FOR (i = 0; i < resample_mem_out_len; i++)
104 : {
105 0 : resample_mem_out[i] = shl(resample_mem_out[i], s);
106 : }
107 :
108 0 : FOR (i = 0; i < 3; i++)
109 : {
110 0 : mem_s12k8[i] = shl(mem_s12k8[i], s);
111 : }
112 : }
113 : /* Store part of current frame as mdct memory buffer and resampler input buffer for next frame */
114 0 : basop_memcpy(mdct_mem32, &x[N - mdct_mem_len], mdct_mem_len * sizeof(Word32));
115 0 : basop_memmove(resamp_mem32, &x[N - resample_mem_in_len], resample_mem_in_len * sizeof(Word32));
116 :
117 : #ifdef DYNMEM_COUNT
118 : Dyn_Mem_Out();
119 : #endif
120 0 : }
121 :
|