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 attack_detector_fx(LC3PLUS_Enc *enc, EncSetup *setup, Word16 *input, Word16 input_scaling, void *scratch)
13 : {
14 : Dyn_Mem_Deluxe_In(
15 : int i, j, position;
16 : Word32 tmp, *block_energy;
17 : Word16 h16, l16, new_scaling, rescale, input_delta_scaling;
18 : Word16 scales[3], *input_16k;
19 : Word16 frame_length_16k;
20 : );
21 :
22 0 : block_energy = scratchAlign(scratch, 0);
23 0 : input_16k = scratchAlign(block_energy, 4 * 4 + 4);
24 0 : frame_length_16k = DEPR_i_mult(enc->attdec_nblocks, 40);
25 :
26 0 : IF (setup->attack_handling)
27 : {
28 : /* input scaling */
29 0 : scales[0] = add(getScaleFactor16(input, enc->frame_length), input_scaling);
30 0 : scales[1] = add(getScaleFactor16_0(setup->attdec_filter_mem, 2), setup->attdec_scaling);
31 0 : scales[2] =
32 0 : shr(add(add(getScaleFactor32_0(&setup->attdec_acc_energy, 1), shl(setup->attdec_scaling, 1)), 1), 1);
33 0 : new_scaling = s_min(scales[0], s_min(scales[1], scales[2]));
34 :
35 0 : new_scaling = sub(new_scaling, 2); /* add overhead for resampler*/
36 :
37 : /* memory re-scaling */
38 0 : rescale = sub(new_scaling, setup->attdec_scaling);
39 :
40 0 : IF (rescale)
41 : {
42 0 : rescale = s_min(s_max(rescale, -15), 15);
43 0 : setup->attdec_filter_mem[0] = shl(setup->attdec_filter_mem[0], rescale); move16();
44 0 : setup->attdec_filter_mem[1] = shl(setup->attdec_filter_mem[1], rescale); move16();
45 0 : setup->attdec_acc_energy = L_shl(setup->attdec_acc_energy, shl(rescale, 1)); move16();
46 : }
47 0 : setup->attdec_scaling = new_scaling; move16();
48 :
49 0 : SWITCH (enc->fs)
50 : {
51 0 : case 32000:
52 0 : input_delta_scaling = sub(1, sub(new_scaling, input_scaling));
53 0 : FOR (i = 0; i < frame_length_16k; i++)
54 : {
55 0 : input_16k[i] = add(shr(input[2 * i + 0], input_delta_scaling),
56 0 : shr(input[2 * i + 1], input_delta_scaling)); move16();
57 : }
58 0 : break;
59 0 : case 48000:
60 0 : input_delta_scaling = sub(2, sub(new_scaling, input_scaling));
61 0 : FOR (i = 0; i < frame_length_16k; i++)
62 : {
63 0 : input_16k[i] = add(shr(input[3 * i + 0], input_delta_scaling),
64 0 : add(shr(input[3 * i + 1], input_delta_scaling),
65 0 : shr(input[3 * i + 2], input_delta_scaling))); move16();
66 : }
67 0 : break;
68 0 : default: ASSERT(!"sampling rate not supported in function attack_detector_fx!"); break;
69 : }
70 :
71 0 : input_16k[-2] = setup->attdec_filter_mem[0]; move16();
72 0 : input_16k[-1] = setup->attdec_filter_mem[1]; move16();
73 0 : setup->attdec_filter_mem[0] = input_16k[frame_length_16k - 2]; move16();
74 0 : setup->attdec_filter_mem[1] = input_16k[frame_length_16k - 1]; move16();
75 :
76 0 : FOR (i = frame_length_16k - 1; i >= 0; i--)
77 : {
78 0 : tmp = L_mult(input_16k[i], 12288);
79 0 : tmp = L_msu(tmp, input_16k[i - 1], 16384);
80 0 : tmp = L_mac(tmp, input_16k[i - 2], 4096);
81 :
82 0 : input_16k[i] = extract_h(tmp); move16();
83 : }
84 :
85 0 : basop_memset(block_energy, 0, 4 * sizeof(Word32));
86 :
87 0 : FOR (j = 0; j < enc->attdec_nblocks; j++)
88 : {
89 0 : FOR (i = 0; i < 40; i++)
90 : {
91 0 : block_energy[j] = L_mac(block_energy[j], input_16k[i + j*40], input_16k[i + j*40]); move16();
92 : }
93 : }
94 :
95 0 : setup->attdec_detected = setup->attdec_position >= enc->attdec_hangover_thresh;
96 0 : test(); move16();
97 0 : position = -1; move16();
98 :
99 0 : FOR (i = 0; i < enc->attdec_nblocks; i++)
100 : {
101 : /* block_energy[i] / 8.5 */
102 0 : l16 = extract_l(L_shr(block_energy[i], 1));
103 0 : l16 = s_and(l16, 0x7fff);
104 0 : h16 = extract_h(block_energy[i]);
105 0 : tmp = L_shr(L_mult0(l16, 30840), 15);
106 0 : tmp = L_shr(L_mac0(tmp, h16, 30840), 2);
107 :
108 0 : IF (tmp > setup->attdec_acc_energy)
109 : {
110 0 : position = i; move16();
111 0 : setup->attdec_detected = 1; move16();
112 : }
113 0 : setup->attdec_acc_energy = L_max(L_shr(setup->attdec_acc_energy, 2), block_energy[i]); move16();
114 : }
115 0 : setup->attdec_position = position; move16();
116 : }
117 :
118 : Dyn_Mem_Deluxe_Out();
119 0 : }
|