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 process_resamp12k8_fx(Word16 x[], Word16 x_len, Word16 mem_in[], Word16 mem_in_len, Word32 mem_50[],
13 : Word16 mem_out[], Word16 mem_out_len, Word16 y[], Word16 *y_len, Word16 fs_idx,
14 : Word16 frame_dms, Word8 *scratchBuffer
15 : , Word16 bps
16 : )
17 : {
18 : Dyn_Mem_Deluxe_In(
19 : Word16 * buf;
20 : Word16 index_int, index_frac, len_12k8;
21 : Word16 resamp_upfac, resamp_off_int, resamp_off_frac, resamp_delay;
22 : const Word16 *resamp_filt;
23 : const Word16 *filt_coeff;
24 : Word16 * filt_input;
25 : Word32 filt_output, mem_50_0, mem_50_1;
26 : Counter n, m;
27 : Word32 L_tmp;
28 : );
29 :
30 0 : buf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * (MAX_LEN + MAX_LEN / 8) bytes */
31 :
32 : /* resamp parameters : {upsample-factor, 120 / upsample-factor, down_sample_int_part, down_sample_frac_part }
33 : upsample is to 384 kHz. upsample-facor = 192000 / samp-freq
34 : Fractional downsample parameters are calculated from : downsample samp-freq to 128000
35 : At 48000 sampling frequency:
36 : upsample-factor = 192000 / 48000 = 4
37 : 120 / upsample-factor = 120 / 4 = 30
38 : downsample-ratio = 48000 / 12800 = 3.75
39 : down_sample_int_part = 3
40 : down_sample_frac_part = int(0.75 * upsample-factor ) = 0.75 * 4 = 3
41 : */
42 0 : resamp_upfac = resamp_params[fs_idx][0]; move16();
43 0 : resamp_delay = resamp_params[fs_idx][1]; move16();
44 0 : resamp_off_int = resamp_params[fs_idx][2]; move16();
45 0 : resamp_off_frac = resamp_params[fs_idx][3]; move16();
46 0 : resamp_filt = resamp_filts[fs_idx]; move16();
47 :
48 0 : len_12k8 = LEN_12K8 / 4 * (frame_dms / 25); move16();
49 0 : *y_len = len_12k8; move16();
50 :
51 : /* Init Input Buffer */
52 0 : basop_memmove(buf, mem_in, mem_in_len * sizeof(Word16));
53 0 : basop_memmove(&buf[mem_in_len], x, x_len * sizeof(Word16));
54 0 : basop_memmove(mem_in, &buf[x_len], mem_in_len * sizeof(Word16));
55 :
56 : /* Init Input Indices */
57 0 : index_int = 1; move16();
58 0 : index_frac = 0; move16();
59 :
60 : /* Resampling */
61 0 : FOR (n = 0; n < len_12k8; n++)
62 : {
63 : /* Init Filtering */
64 0 : filt_input = &buf[index_int];
65 0 : filt_coeff = &resamp_filt[index_frac * resamp_delay * 2];
66 :
67 : /* Perform Filtering */
68 0 : filt_output = L_mult0(*filt_input, *filt_coeff);
69 0 : FOR (m = 1; m < resamp_delay * 2; m++)
70 : {
71 0 : filt_coeff++;
72 0 : filt_input++;
73 0 : if (*filt_coeff)
74 : {
75 0 : filt_output = L_mac0(filt_output, *filt_input, *filt_coeff);
76 : }
77 : }
78 0 : y[n] = round_fx(filt_output); move16();
79 :
80 : /* Update Input Indices */
81 0 : index_int = add(index_int, resamp_off_int);
82 0 : index_frac = add(index_frac, resamp_off_frac);
83 0 : IF (sub(resamp_upfac, index_frac) <= 0)
84 : {
85 0 : index_int = add(index_int, 1);
86 0 : index_frac = sub(index_frac, resamp_upfac);
87 : }
88 : }
89 :
90 : /* High Pass Filtering (-3dB at 50Hz) */
91 0 : mem_50_0 = mem_50[0]; move32();
92 0 : mem_50_1 = mem_50[1]; move32();
93 :
94 0 : FOR (n = 0; n < len_12k8; n++)
95 : {
96 0 : filt_output = L_mac0_sat(mem_50_0, highpass50_filt_num[0], y[n]);
97 0 : L_tmp = L_mac0(Mpy_32_16_lc3plus(filt_output, highpass50_filt_den[0]), highpass50_filt_num[1], y[n]);
98 :
99 0 : IF (sub(bps, 24) == 0)
100 : {
101 0 : mem_50_0 = L_shl_sat(L_add_sat(L_shr_pos(mem_50_1,1), L_tmp), 1);
102 : } ELSE
103 : {
104 0 : mem_50_0 = L_add_sat(mem_50_1, L_shl_sat(L_tmp, 1));
105 : }
106 :
107 0 : mem_50_1 = L_mac0(Mpy_32_16_lc3plus(filt_output, highpass50_filt_den[1]), highpass50_filt_num[2], y[n]);
108 0 : y[n] = round_fx_sat(filt_output); move16();
109 : }
110 0 : mem_50[0] = mem_50_0; move32();
111 0 : mem_50[1] = mem_50_1; move32();
112 :
113 : /* Output Buffer */
114 0 : basop_memmove(buf, mem_out, mem_out_len * sizeof(Word16));
115 0 : basop_memmove(&buf[mem_out_len], y, len_12k8 * sizeof(Word16));
116 0 : basop_memmove(y, buf, (*y_len + 1) * sizeof(Word16));
117 0 : basop_memmove(mem_out, &buf[len_12k8], mem_out_len * sizeof(Word16));
118 :
119 : Dyn_Mem_Deluxe_Out();
120 0 : }
121 :
|