mirror of
https://github.com/google/liblc3.git
synced 2026-04-18 05:35:31 +00:00
Duplicate interfaces for HR mode spec: Remove intermediate quantized table fix: legacy lc3_frame_bytes() and lc3_resolve_bitrate() Cosmetic: rename fast_xxx math function to lc3_xxx
93 lines
2.9 KiB
C
93 lines
2.9 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright 2022 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
******************************************************************************/
|
|
|
|
#include "attdet.h"
|
|
|
|
|
|
/**
|
|
* Time domain attack detector
|
|
*/
|
|
bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr,
|
|
int nbytes, struct lc3_attdet_analysis *attdet, const int16_t *x)
|
|
{
|
|
/* --- Check enabling --- */
|
|
|
|
const int nbytes_ranges[][LC3_NUM_SRATE - LC3_SRATE_32K][2] = {
|
|
[LC3_DT_7M5 - LC3_DT_7M5] = { { 61, 149 }, { 75, 149 } },
|
|
[LC3_DT_10M - LC3_DT_7M5] = { { 81, INT_MAX }, { 100, INT_MAX } },
|
|
};
|
|
|
|
if (dt < LC3_DT_7M5 || sr < LC3_SRATE_32K || lc3_hr(sr) ||
|
|
nbytes < nbytes_ranges[dt - LC3_DT_7M5][sr - LC3_SRATE_32K][0] ||
|
|
nbytes > nbytes_ranges[dt - LC3_DT_7M5][sr - LC3_SRATE_32K][1] )
|
|
return 0;
|
|
|
|
/* --- Filtering & Energy calculation --- */
|
|
|
|
int nblk = 4 - (dt == LC3_DT_7M5);
|
|
int32_t e[4];
|
|
|
|
for (int i = 0; i < nblk; i++) {
|
|
e[i] = 0;
|
|
|
|
if (sr == LC3_SRATE_32K) {
|
|
int16_t xn2 = (x[-4] + x[-3]) >> 1;
|
|
int16_t xn1 = (x[-2] + x[-1]) >> 1;
|
|
int16_t xn, xf;
|
|
|
|
for (int j = 0; j < 40; j++, x += 2, xn2 = xn1, xn1 = xn) {
|
|
xn = (x[0] + x[1]) >> 1;
|
|
xf = (3 * xn - 4 * xn1 + 1 * xn2) >> 3;
|
|
e[i] += (xf * xf) >> 5;
|
|
}
|
|
}
|
|
|
|
else {
|
|
int16_t xn2 = (x[-6] + x[-5] + x[-4]) >> 2;
|
|
int16_t xn1 = (x[-3] + x[-2] + x[-1]) >> 2;
|
|
int16_t xn, xf;
|
|
|
|
for (int j = 0; j < 40; j++, x += 3, xn2 = xn1, xn1 = xn) {
|
|
xn = (x[0] + x[1] + x[2]) >> 2;
|
|
xf = (3 * xn - 4 * xn1 + 1 * xn2) >> 3;
|
|
e[i] += (xf * xf) >> 5;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* --- Attack detection ---
|
|
* The attack block `p_att` is defined as the normative value + 1,
|
|
* in such way, it will be initialized to 0 */
|
|
|
|
int p_att = 0;
|
|
int32_t a[4];
|
|
|
|
for (int i = 0; i < nblk; i++) {
|
|
a[i] = LC3_MAX(attdet->an1 >> 2, attdet->en1);
|
|
attdet->en1 = e[i], attdet->an1 = a[i];
|
|
|
|
if ((e[i] >> 3) > a[i] + (a[i] >> 4))
|
|
p_att = i + 1;
|
|
}
|
|
|
|
int att = attdet->p_att >= 1 + (nblk >> 1) || p_att > 0;
|
|
attdet->p_att = p_att;
|
|
|
|
return att;
|
|
}
|