xref: /btstack/3rd-party/lc3-google/src/attdet.c (revision 4a9eead824c50b40e12b6f72611a74a3f57a47f6)
1 /******************************************************************************
2  *
3  *  Copyright 2021 Google, Inc.
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 
19 #include "attdet.h"
20 
21 
22 /**
23  * Time domain attack detector
24  */
25 bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr,
26     int nbytes, struct lc3_attdet_analysis *attdet, const float *x)
27 {
28     /* --- Check enabling --- */
29 
30     const int nbytes_ranges[LC3_NUM_DT][LC3_NUM_SRATE - LC3_SRATE_32K][2] = {
31             [LC3_DT_7M5] = { { 61,     149 }, {  75,     149 } },
32             [LC3_DT_10M] = { { 81, INT_MAX }, { 100, INT_MAX } },
33     };
34 
35     if (sr < LC3_SRATE_32K ||
36             nbytes < nbytes_ranges[dt][sr - LC3_SRATE_32K][0] ||
37             nbytes > nbytes_ranges[dt][sr - LC3_SRATE_32K][1]   )
38         return 0;
39 
40     /* --- Filtering & Energy calculation --- */
41 
42     int nblk = 4 - (dt == LC3_DT_7M5);
43     float e[4];
44 
45     for (int i = 0; i < nblk; i++) {
46         e[i] = 0;
47 
48         if (sr == LC3_SRATE_32K) {
49             float xn2 = x[-4] + x[-3];
50             float xn1 = x[-2] + x[-1];
51             float xn, xf;
52 
53             for (int j = 0; j < 40; j++, x += 2, xn2 = xn1, xn1 = xn) {
54                 xn = x[0] + x[1];
55                 xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2;
56                 e[i] += xf * xf;
57             }
58         }
59 
60         else {
61             float xn2 = x[-6] + x[-5] + x[-4];
62             float xn1 = x[-3] + x[-2] + x[-1];
63             float xn, xf;
64 
65             for (int j = 0; j < 40; j++, x += 3, xn2 = xn1, xn1 = xn) {
66                 xn = x[0] + x[1] + x[2];
67                 xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2;
68                 e[i] += xf * xf;
69             }
70         }
71     }
72 
73     /* --- Attack detection ---
74      * The attack block `p_att` is defined as the normative value + 1,
75      * in such way, it will be initialized to 0 */
76 
77     int p_att = 0;
78     float a[4];
79 
80     for (int i = 0; i < nblk; i++) {
81         a[i] = fmaxf(0.25 * attdet->an1, attdet->en1);
82         attdet->en1 = e[i], attdet->an1 = a[i];
83 
84         if (e[i] > 8.5 * a[i])
85             p_att = i + 1;
86     }
87 
88     int att = attdet->p_att >= 1 + (nblk >> 1) || p_att > 0;
89     attdet->p_att = p_att;
90 
91     return att;
92 }
93