xref: /btstack/3rd-party/lc3-google/src/attdet.c (revision 9a19cd786042b1fc78813d984efdd045e84593df)
1*9a19cd78SMatthias Ringwald /******************************************************************************
2*9a19cd78SMatthias Ringwald  *
3*9a19cd78SMatthias Ringwald  *  Copyright 2021 Google, Inc.
4*9a19cd78SMatthias Ringwald  *
5*9a19cd78SMatthias Ringwald  *  Licensed under the Apache License, Version 2.0 (the "License");
6*9a19cd78SMatthias Ringwald  *  you may not use this file except in compliance with the License.
7*9a19cd78SMatthias Ringwald  *  You may obtain a copy of the License at:
8*9a19cd78SMatthias Ringwald  *
9*9a19cd78SMatthias Ringwald  *  http://www.apache.org/licenses/LICENSE-2.0
10*9a19cd78SMatthias Ringwald  *
11*9a19cd78SMatthias Ringwald  *  Unless required by applicable law or agreed to in writing, software
12*9a19cd78SMatthias Ringwald  *  distributed under the License is distributed on an "AS IS" BASIS,
13*9a19cd78SMatthias Ringwald  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*9a19cd78SMatthias Ringwald  *  See the License for the specific language governing permissions and
15*9a19cd78SMatthias Ringwald  *  limitations under the License.
16*9a19cd78SMatthias Ringwald  *
17*9a19cd78SMatthias Ringwald  ******************************************************************************/
18*9a19cd78SMatthias Ringwald 
19*9a19cd78SMatthias Ringwald #include "attdet.h"
20*9a19cd78SMatthias Ringwald 
21*9a19cd78SMatthias Ringwald 
22*9a19cd78SMatthias Ringwald /**
23*9a19cd78SMatthias Ringwald  * Time domain attack detector
24*9a19cd78SMatthias Ringwald  */
25*9a19cd78SMatthias Ringwald bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr,
26*9a19cd78SMatthias Ringwald     int nbytes, struct lc3_attdet_analysis *attdet, const float *x)
27*9a19cd78SMatthias Ringwald {
28*9a19cd78SMatthias Ringwald     /* --- Check enabling --- */
29*9a19cd78SMatthias Ringwald 
30*9a19cd78SMatthias Ringwald     const int nbytes_ranges[LC3_NUM_DT][LC3_NUM_SRATE - LC3_SRATE_32K][2] = {
31*9a19cd78SMatthias Ringwald             [LC3_DT_7M5] = { { 61,     149 }, {  75,     149 } },
32*9a19cd78SMatthias Ringwald             [LC3_DT_10M] = { { 81, INT_MAX }, { 100, INT_MAX } },
33*9a19cd78SMatthias Ringwald     };
34*9a19cd78SMatthias Ringwald 
35*9a19cd78SMatthias Ringwald     if (sr < LC3_SRATE_32K ||
36*9a19cd78SMatthias Ringwald             nbytes < nbytes_ranges[dt][sr - LC3_SRATE_32K][0] ||
37*9a19cd78SMatthias Ringwald             nbytes > nbytes_ranges[dt][sr - LC3_SRATE_32K][1]   )
38*9a19cd78SMatthias Ringwald         return 0;
39*9a19cd78SMatthias Ringwald 
40*9a19cd78SMatthias Ringwald     /* --- Filtering & Energy calculation --- */
41*9a19cd78SMatthias Ringwald 
42*9a19cd78SMatthias Ringwald     int nblk = 4 - (dt == LC3_DT_7M5);
43*9a19cd78SMatthias Ringwald     float e[4];
44*9a19cd78SMatthias Ringwald 
45*9a19cd78SMatthias Ringwald     for (int i = 0; i < nblk; i++) {
46*9a19cd78SMatthias Ringwald         e[i] = 0;
47*9a19cd78SMatthias Ringwald 
48*9a19cd78SMatthias Ringwald         if (sr == LC3_SRATE_32K) {
49*9a19cd78SMatthias Ringwald             float xn2 = x[-4] + x[-3];
50*9a19cd78SMatthias Ringwald             float xn1 = x[-2] + x[-1];
51*9a19cd78SMatthias Ringwald             float xn, xf;
52*9a19cd78SMatthias Ringwald 
53*9a19cd78SMatthias Ringwald             for (int j = 0; j < 40; j++, x += 2, xn2 = xn1, xn1 = xn) {
54*9a19cd78SMatthias Ringwald                 xn = x[0] + x[1];
55*9a19cd78SMatthias Ringwald                 xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2;
56*9a19cd78SMatthias Ringwald                 e[i] += xf * xf;
57*9a19cd78SMatthias Ringwald             }
58*9a19cd78SMatthias Ringwald         }
59*9a19cd78SMatthias Ringwald 
60*9a19cd78SMatthias Ringwald         else {
61*9a19cd78SMatthias Ringwald             float xn2 = x[-6] + x[-5] + x[-4];
62*9a19cd78SMatthias Ringwald             float xn1 = x[-3] + x[-2] + x[-1];
63*9a19cd78SMatthias Ringwald             float xn, xf;
64*9a19cd78SMatthias Ringwald 
65*9a19cd78SMatthias Ringwald             for (int j = 0; j < 40; j++, x += 3, xn2 = xn1, xn1 = xn) {
66*9a19cd78SMatthias Ringwald                 xn = x[0] + x[1] + x[2];
67*9a19cd78SMatthias Ringwald                 xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2;
68*9a19cd78SMatthias Ringwald                 e[i] += xf * xf;
69*9a19cd78SMatthias Ringwald             }
70*9a19cd78SMatthias Ringwald         }
71*9a19cd78SMatthias Ringwald     }
72*9a19cd78SMatthias Ringwald 
73*9a19cd78SMatthias Ringwald     /* --- Attack detection ---
74*9a19cd78SMatthias Ringwald      * The attack block `p_att` is defined as the normative value + 1,
75*9a19cd78SMatthias Ringwald      * in such way, it will be initialized to 0 */
76*9a19cd78SMatthias Ringwald 
77*9a19cd78SMatthias Ringwald     int p_att = 0;
78*9a19cd78SMatthias Ringwald     float a[4];
79*9a19cd78SMatthias Ringwald 
80*9a19cd78SMatthias Ringwald     for (int i = 0; i < nblk; i++) {
81*9a19cd78SMatthias Ringwald         a[i] = fmaxf(0.25 * attdet->an1, attdet->en1);
82*9a19cd78SMatthias Ringwald         attdet->en1 = e[i], attdet->an1 = a[i];
83*9a19cd78SMatthias Ringwald 
84*9a19cd78SMatthias Ringwald         if (e[i] > 8.5 * a[i])
85*9a19cd78SMatthias Ringwald             p_att = i + 1;
86*9a19cd78SMatthias Ringwald     }
87*9a19cd78SMatthias Ringwald 
88*9a19cd78SMatthias Ringwald     int att = attdet->p_att >= 1 + (nblk >> 1) || p_att > 0;
89*9a19cd78SMatthias Ringwald     attdet->p_att = p_att;
90*9a19cd78SMatthias Ringwald 
91*9a19cd78SMatthias Ringwald     return att;
92*9a19cd78SMatthias Ringwald }
93