diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj
index eb2a91d36d82a5c4e5b6e59875c7ace8ea8d03db..8531f39e53e198987dc8bbc6b0f7657d64b2cbfa 100644
--- a/Workspace_msvc/lib_lc3plus.vcxproj
+++ b/Workspace_msvc/lib_lc3plus.vcxproj
@@ -106,6 +106,7 @@
+
@@ -116,7 +117,7 @@
-
+
@@ -153,9 +154,9 @@
-
-
-
+
+
+
@@ -169,9 +170,9 @@
-
-
-
+
+
+
@@ -180,4 +181,4 @@
-
\ No newline at end of file
+
diff --git a/lib_isar/isar_lc3plus_common.c b/lib_isar/isar_lc3plus_common.c
index 7f11ad384778273b34b9c73719be6af751557154..f7fe0db32ebeba38eeec378a57c47154a8031046 100644
--- a/lib_isar/isar_lc3plus_common.c
+++ b/lib_isar/isar_lc3plus_common.c
@@ -33,7 +33,7 @@
#include "options.h"
#include "isar_lc3plus_common.h"
#include "ivas_error.h"
-#include "lc3.h"
+#include "lc3plus.h"
/*-----------------------------------------------------------------------------------------*
* Function ISAR_LC3PLUS_LC3plusErrToIvasErr()
@@ -57,6 +57,13 @@ ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr(
return IVAS_ERR_INTERNAL;
}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function IVAS_LC3PLUS_LC3plusRtpErrToIvasErr()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr(
const LC3PLUS_RTP_ERR lc3PlusRtpError )
{
@@ -85,3 +92,27 @@ ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr(
return IVAS_ERR_UNKNOWN;
}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function IVAS_LC3PLUS_UsToLC3plusFrameDuration()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
+LC3PLUS_FrameDuration IVAS_LC3PLUS_UsToLC3plusFrameDuration(
+ const int16_t lc3PlusFrameDurationUs )
+{
+ switch ( lc3PlusFrameDurationUs )
+ {
+ case 2500:
+ return LC3PLUS_FRAME_DURATION_2p5MS;
+ case 5000:
+ return LC3PLUS_FRAME_DURATION_5MS;
+ case 10000:
+ return LC3PLUS_FRAME_DURATION_10MS;
+ default:
+ break;
+ }
+
+ return LC3PLUS_FRAME_DURATION_UNDEFINED;
+}
diff --git a/lib_isar/isar_lc3plus_common.h b/lib_isar/isar_lc3plus_common.h
index 2638ea8a9cbb34fca0705c0b84e46692e34e9a19..3b52e5b3f15c0ce29c25f7d640140530db05afb6 100644
--- a/lib_isar/isar_lc3plus_common.h
+++ b/lib_isar/isar_lc3plus_common.h
@@ -37,7 +37,7 @@
#include
#include "options.h"
#include "ivas_error.h"
-#include "lc3.h"
+#include "lc3plus.h"
#include "isar_lc3plus_payload.h"
/*! common configuration parameters between encoder and decoder */
@@ -45,7 +45,7 @@ typedef struct LC3PLUS_CONFIG
{
/*! frame duration in microseconds [10000, 5000, 2500] */
int16_t lc3plus_frame_duration_us;
- /*! isar frame duration in microseconds [20000, 10000, 5000] */
+ /*! ISAR frame duration in microseconds [20000, 10000, 5000] */
int16_t isar_frame_duration_us;
/*! sampling rate*/
int32_t samplerate;
@@ -61,4 +61,7 @@ ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError );
/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */
ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError );
+/*! utility function to convert a value in microseconds to an LC3PLUS_FrameDuration */
+LC3PLUS_FrameDuration IVAS_LC3PLUS_UsToLC3plusFrameDuration( const int16_t lc3PlusFrameDuration );
+
#endif /* ISAR_LC3PLUS_COM_H */
diff --git a/lib_isar/isar_lc3plus_dec.c b/lib_isar/isar_lc3plus_dec.c
index f097aec143164db122a26a08d6b04a85667ba1ef..5f7d1d2cf69d9a6ec72fd5a503eea9650b95d964 100644
--- a/lib_isar/isar_lc3plus_dec.c
+++ b/lib_isar/isar_lc3plus_dec.c
@@ -36,7 +36,7 @@
#include "ivas_prot.h"
#include "isar_lc3plus_dec.h"
#include "isar_lc3plus_common.h"
-#include "lc3.h"
+#include "lc3plus.h"
#include "ivas_error_utils.h"
#include "wmc_auto.h"
@@ -135,7 +135,7 @@ ivas_error ISAR_LC3PLUS_DEC_Open(
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" );
}
- err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 );
+ err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], IVAS_LC3PLUS_UsToLC3plusFrameDuration( config.lc3plus_frame_duration_us ) );
if ( LC3PLUS_OK != err )
{
ISAR_LC3PLUS_DEC_Close( handle );
diff --git a/lib_isar/isar_lc3plus_dec.h b/lib_isar/isar_lc3plus_dec.h
index 99e7d09eff5d5634e8a771da2bc90234d256de26..be5b22d459f5060da018d85b47005134fd05b7fc 100644
--- a/lib_isar/isar_lc3plus_dec.h
+++ b/lib_isar/isar_lc3plus_dec.h
@@ -35,7 +35,7 @@
#include
#include "options.h"
-#include "lc3.h"
+#include "lc3plus.h"
#include "ivas_error.h"
#include "ivas_cnst.h"
#include "isar_lc3plus_common.h"
diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c
index 725a01d2974a1b352accd35b32afa141c55d912e..707dcda003463e02d49c1118c09ddc386e2827b9 100644
--- a/lib_isar/isar_lc3plus_enc.c
+++ b/lib_isar/isar_lc3plus_enc.c
@@ -32,7 +32,7 @@
#include "isar_lc3plus_enc.h"
#include "isar_lc3plus_common.h"
-#include "lc3.h"
+#include "lc3plus.h"
#include "ivas_error_utils.h"
#include "prot.h"
#include "wmc_auto.h"
@@ -162,7 +162,7 @@ ivas_error ISAR_LC3PLUS_ENC_Open(
return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" );
}
- err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 );
+ err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], IVAS_LC3PLUS_UsToLC3plusFrameDuration( config.lc3plus_frame_duration_us ) );
if ( err != LC3PLUS_OK )
{
ISAR_LC3PLUS_ENC_Close( handle );
diff --git a/lib_isar/isar_lc3plus_enc.h b/lib_isar/isar_lc3plus_enc.h
index 9c80033fd36a9d7fea205bd63bb9497611131167..ed6c526011d7a4861dd040ae4d6b3696437aa578 100644
--- a/lib_isar/isar_lc3plus_enc.h
+++ b/lib_isar/isar_lc3plus_enc.h
@@ -35,7 +35,7 @@
#include
#include "ivas_error.h"
-#include "lc3.h"
+#include "lc3plus.h"
#include "isar_lc3plus_common.h"
#include "isar_lc3plus_payload.h"
diff --git a/lib_isar/isar_lc3plus_payload.h b/lib_isar/isar_lc3plus_payload.h
index e95128578493f5561fdcb2292aef37f0c202e428..580a58ca651defe96eeb84229b8f07b3407a756c 100644
--- a/lib_isar/isar_lc3plus_payload.h
+++ b/lib_isar/isar_lc3plus_payload.h
@@ -35,7 +35,7 @@
#include
#include
-#include "lc3.h"
+#include "lc3plus.h"
#include "options.h"
diff --git a/lib_lc3plus/adjust_global_gain.c b/lib_lc3plus/adjust_global_gain.c
index d5c122d525bb06ddb3cc68b370f59cd7fa51058f..1de3585fcdf6637bda406a965cc6599d9d951bd2 100644
--- a/lib_lc3plus/adjust_global_gain.c
+++ b/lib_lc3plus/adjust_global_gain.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -12,7 +12,7 @@
#include "functions.h"
void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits, LC3_INT* gainChange, LC3_INT fs_idx
- , LC3_INT16 hrmode, LC3_INT16 frame_dms
+ , LC3_INT16 hrmode, LC3PLUS_FrameDuration frame_dms
)
{
LC3_FLOAT delta;
@@ -20,7 +20,7 @@ void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_
LC3_INT gg_idx_inc;
LC3_FLOAT factor;
- if (frame_dms == 25)
+ if (frame_dms == LC3PLUS_FRAME_DURATION_2p5MS)
{
if (target < 520)
{
@@ -28,11 +28,11 @@ void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_
} else {
factor = 4;
}
- } else if (frame_dms == 50)
+ } else if (frame_dms == LC3PLUS_FRAME_DURATION_5MS)
{
factor = 2;
}
- else if (frame_dms == 75)
+ else if (frame_dms == LC3PLUS_FRAME_DURATION_7p5MS)
{
factor = 1.2;
}
diff --git a/lib_lc3plus/al_fec_fl.c b/lib_lc3plus/al_fec_fl.c
index adae19dc394aa7e04cffb95af2257f03433cd073..9b7276f23732ccd64bc458351930e5c226529731 100644
--- a/lib_lc3plus/al_fec_fl.c
+++ b/lib_lc3plus/al_fec_fl.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -500,11 +500,12 @@ void fec_encoder(LC3_INT16 mode, LC3_INT16 epmr, LC3_UINT8 *iobuf, LC3_INT16 dat
assert((slot_bytes >= FEC_SLOT_BYTES_MIN && slot_bytes <= FEC_SLOT_BYTES_MAX) &&
"fec_encoder: slot_bytes out of range");
- tmp -= mode == 1 ? 1 : n_codewords * (mode - 1); // reed solomon redundancy
- tmp -= slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode]; // crc1
- tmp -= (n_pccw > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0; // crc2
+ tmp -= mode == 1 ? 1 : n_codewords * (mode - 1); /* reed solomon redundancy */
+ tmp -= slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode]; /* crc1 */
+ tmp -= (n_pccw > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0; /* crc2 */
assert(data_bytes == tmp && "fec_encoder: inconsistent payload size");
assert(n_codewords - n_pccw >= 6);
+ (void)tmp;
}
/* data preproc: re-ordering and hash extension */
@@ -1194,7 +1195,7 @@ FEC_STATIC LC3_INT32 rs16_detect_and_correct(LC3_UINT8 *iobuf, LC3_INT32 n_symb,
}
}
}
- assert(n_mode_candidates <= 4); // suppress false gcc warning when OPTIM=3
+ assert(n_mode_candidates <= 4); /* suppress false gcc warning when OPTIM=3 */
/* sort mode candidates by risk */
for (i = 0; i < n_mode_candidates; i++)
diff --git a/lib_lc3plus/apply_global_gain.c b/lib_lc3plus/apply_global_gain.c
index 48305676cd334408aec56e6d22f3a2e493c11dcd..107a9ff497e5341f6a72bad957ba8b561b366360 100644
--- a/lib_lc3plus/apply_global_gain.c
+++ b/lib_lc3plus/apply_global_gain.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/ari_codec.c b/lib_lc3plus/ari_codec.c
index 2a76ecac8338b848957fd73b96f480d930038317..4721a4c1e69b5b365e01b7ebec6d74a5a7808eef 100644
--- a/lib_lc3plus/ari_codec.c
+++ b/lib_lc3plus/ari_codec.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -90,7 +90,9 @@ static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT3
{
bp_side_local = bp_side_local + 1;
}
- } else {
+ }
+ else
+ {
bp_local = bp_local - 1;
}
@@ -131,12 +133,16 @@ static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT3
if (st_fl->pc_bfi == 2)
{
-
+#ifdef CR13_B_FIX_PC_BINS
+ if (st_fl->pc_c_bp_side && (*bp_side + 1) <= st_fl->pc_be_bp_right)
+#else
if ((st_fl->pc_c_bp && (*bp + 1) >= st_fl->pc_be_bp_left) || (st_fl->pc_c_bp_side && (*bp_side + 1) <= st_fl->pc_be_bp_right))
+#endif
{
st_fl->pc_inv_bin = cur_bin;
return 1;
- } else if ((st_fl->pc_c_bp && *bp >= 0) || (st_fl->pc_c_bp_side && *bp_side <= (st_fl->pc_bytes - 1)))
+ }
+ else if ((st_fl->pc_c_bp && *bp >= 0) || (st_fl->pc_c_bp_side && *bp_side <= (st_fl->pc_bytes - 1)))
{
st_fl->pc_inv_bin = MIN(st_fl->pc_inv_bin, cur_bin);
return 0;
@@ -147,9 +153,56 @@ static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT3
#ifdef WMOPS
pop_wmops();
-#endif
+#endif
+ return 0;
+}
+
+#ifdef CR13_B_FIX_PC_BINS
+static LC3_INT16 pc_check_bytes_ac_decode(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32* bp_side, LC3_INT16 cur_bin)
+{
+ LC3_INT32 bp_local, bp_side_local;
+#ifdef WMOPS
+ push_wmops("pc_check_bytes");
+#endif
+
+ if (st_fl->pc_bytes > 0)
+ {
+ bp_local = *bp;
+ bp_side_local = *bp_side;
+
+ if (from_left)
+ {
+ if (mask_side == 1)
+ {
+ bp_side_local = bp_side_local + 1;
+ }
+ }
+ else
+ {
+ bp_local = bp_local - 1;
+ }
+
+
+ if (!st_fl->pc_enc && st_fl->pc_b_right > -1)
+ {
+
+ if (st_fl->pc_bfi == 2)
+ {
+ if ((st_fl->pc_c_bp && (*bp) > st_fl->pc_be_bp_left))
+ {
+ st_fl->pc_inv_bin = cur_bin;
+ return 1;
+ }
+ }
+ }
+ }
+
+#ifdef WMOPS
+ pop_wmops();
+#endif
return 0;
}
+#endif
void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side)
{
@@ -184,15 +237,25 @@ LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* freq, LC3_INT32 nu
push_wmops("ac_decode_fl");
#endif
+#ifdef CR13_B_FIX_PC_BINS
+ if (pc_check_bytes_ac_decode(bp, st, from_left, mask_side, bp_side, cur_bin) != 0)
+ {
+ st->BER_detect = 1;
+ return 0;
+ }
+#endif
+
tmp = st->ac_range_fl >> 10;
- if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) {
+ if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10))
+ {
st->BER_detect = 1;
}
val = num_sym - 1;
- while (st->ac_low_fl < (LC3_UINT32)(tmp * freq[val])) {
+ while (st->ac_low_fl < (LC3_UINT32)(tmp * freq[val]))
+ {
val--;
}
@@ -201,7 +264,8 @@ LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* freq, LC3_INT32 nu
st->ac_low_fl = st->ac_low_fl - tmp * freq[val];
st->ac_range_fl = tmp * symfreq_loc;
- while (st->ac_range_fl < 65536) {
+ while (st->ac_range_fl < 65536)
+ {
st->ac_low_fl = ((LC3_INT32)st->ac_low_fl) & ((LC3_INT32)(16777215));
if(pc_check_bytes(bp, st, from_left, mask_side, bp_side, cur_bin) != 0)
@@ -209,7 +273,7 @@ LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* freq, LC3_INT32 nu
st->BER_detect = 1;
return 1;
}
-
+
st->ac_low_fl = st->ac_low_fl << 8;
st->ac_low_fl = st->ac_low_fl + ptr[*bp];
*bp = *bp + 1;
@@ -241,7 +305,7 @@ void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT*
void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting,
LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx,
LC3_INT gg_idx, uint8_t * resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes,
- LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3_INT frame_dms,
+ LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3PLUS_FrameDuration frame_dms,
LC3_INT32 n_pc, LC3_INT32 be_bp_left, LC3_INT32 be_bp_right, LC3_INT32 enc, LC3_INT32 *b_left, LC3_INT32 *spec_inv_idx,
LC3_INT hrmode
)
@@ -298,7 +362,7 @@ void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side,
tmp = MAXLAG;
- if (frame_dms <= 50)
+ if (frame_dms <= LC3PLUS_FRAME_DURATION_5MS)
{
tmp /= 2;
}
@@ -334,11 +398,13 @@ void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side,
}
/* Spectral data */
- for (k = 0; k < lastnz; k = k + 2) {
+ for (k = 0; k < lastnz; k = k + 2)
+ {
/* Context */
t = c + rateFlag;
- if (k > (L_spec >> 1)) {
+ if (k > (L_spec >> 1))
+ {
t = t + 256;
}
@@ -346,23 +412,29 @@ void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side,
x[k] = 0;
x[k + 1] = 0;
- if (hrmode == 1) {
+ if (hrmode == 1)
+ {
max_lev = 13 + 8;
- } else {
+ }
+ else
+ {
max_lev = 13;
}
- for (lev = 0; lev <= max_lev; lev++) {
+ for (lev = 0; lev <= max_lev; lev++)
+ {
lev1 = MIN(lev, 3);
pki = ari_spec_lookup_fl[t + lev1 * 1024];
sym = ac_decode_fl(&st, &ari_spec_cumfreq_fl[pki][0], 17, ptr, &bp, 1, mask_side, &bp_side, k);
- if (sym < 16) {
+ if (sym < 16)
+ {
break;
}
- if (lsbMode == 0 || lev > 0) {
+ if (lsbMode == 0 || lev > 0)
+ {
if(pc_check_bytes(&bp, &st, 0, mask_side, &bp_side, k) != 0)
{
goto ber_detect;
@@ -495,6 +567,12 @@ void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side,
{
idx_len *= EXT_RES_ITER_MAX;
}
+#ifdef CR9_C_ADD_1p25MS
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ idx_len *= 3;
+ }
+#endif
+
*nbits_residual = MIN(*nbits_residual, idx_len);
*residualPresent = 1;
diff --git a/lib_lc3plus/attack_detector.c b/lib_lc3plus/attack_detector.c
index 10e3617c8b1e6d53fbde11f5f81143b76aebb486..b74a320563c5aa7750c600b104d86cdf457d8fea 100644
--- a/lib_lc3plus/attack_detector.c
+++ b/lib_lc3plus/attack_detector.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/clib.h b/lib_lc3plus/clib.h
index 7d2fb7bb10ee010a4abd381340c9a370b0fd5525..51970ef1465511dc6b0ef324b7f7d438e3e727e2 100644
--- a/lib_lc3plus/clib.h
+++ b/lib_lc3plus/clib.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/setup_com_lc3.c b/lib_lc3plus/com_entropy.c
similarity index 60%
rename from lib_lc3plus/setup_com_lc3.c
rename to lib_lc3plus/com_entropy.c
index f37af56a3109e415bed3f7d2d49507c99ffa5bed..da7ee8edaa89db77882e811c08dbdbc4de5355dd 100644
--- a/lib_lc3plus/setup_com_lc3.c
+++ b/lib_lc3plus/com_entropy.c
@@ -1,31 +1,29 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
* estoppel or otherwise. *
******************************************************************************/
-
+
#include "options.h"
#include "wmc_auto.h"
#include "functions.h"
-LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len)
+LC3_INT16 getLastNzBits (LC3_INT16 N)
{
- LC3_FLOAT max;
- LC3_INT32 i;
-
- max = LC3_FABS(in[0]);
-
- for (i = 0; i < len; i++)
+ LC3_INT16 minBits;
+
+ minBits = ceil(LC3_LOGTWO(N >> 1));
+#ifdef CR9_C_ADD_1p25MS
+ /* minimum of 2 spare bits */
+ if (((1 << minBits) - (N >> 1)) < 2)
{
- if (LC3_FABS(in[i]) > LC3_FABS(max))
- {
- max = LC3_FABS(in[i]);
- }
+ minBits++;
}
-
- return max;
+#endif
+
+ return minBits;
}
diff --git a/lib_lc3plus/constants.c b/lib_lc3plus/constants.c
index 047b21226d4c1503f1e6735b860c56831dc62a09..1040d0098af1917fd973bd93cfa3a78ef52d2d02 100644
--- a/lib_lc3plus/constants.c
+++ b/lib_lc3plus/constants.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,6 +11,731 @@
#include "wmc_auto.h"
#include "functions.h"
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+/* Stage 1 section A */
+const LC3_FLOAT lrsns_st1A_topTab_1bitNoDC[2 * 16] = { /*[2][16] = */
+ /* idx0 --> flat: no additional perceptual weighting than tilt */
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+
+ /* : idx1 */ /* Q11 quantized */
+ +1.187011718750000e+00, +1.014160156250000e+00, +7.773437500000000e-01, +4.023437500000000e-01, +7.812500000000000e-03, -2.636718750000000e-01, -2.734375000000000e-01, -2.617187500000000e-01,
+ -7.519531250000000e-02, +1.879882812500000e-01, +4.526367187500000e-01, +5.512695312500000e-01, +2.221679687500000e-01, -3.710937500000000e-01, -1.253417968750000e+00, -2.304199218750000e+00
+};
+
+/* compressed c_domain indexes for merged CB st1B */
+
+const LC3_INT16 lrsns_st1B_merged170orderSortedSegmCnt[4] = {
+ 88, 42, 24, 16
+};
+const LC3_INT16 lrsns_st1B_merged170orderSortedSegmCum[5] = {
+ 0, 88, 130, 154, 170
+};
+
+/* each index point to two vectors in the split 2x32 stage 1 cb , lower 12 bits in use [1][5][1][5] */
+/* bits b13,b12 are ff,fr,rf,rr , handled by counting the cumulative idx */
+const LC3_INT16 lrsns_st1B_merged170orderSort12bitIdx[170] = {
+ 15, 19, 119, 162, 177, 185, 227, 296, 297, 353, 357, 369, 370, 372, 377, 416, 418,
+ 420, 515, 529, 561, 569, 603, 625, 627, 673, 680, 754, 756, 777, 786, 801, 809, 834,
+ 837, 848, 849, 850, 852, 864, 865, 866, 872, 904, 908, 913, 914, 924, 928, 978, 996,
+ 1041, 1082, 1088, 1089, 1090, 1139, 1651, 1751, 1982, 1999, 2066, 2120, 2194, 2247, 2391, 2495, 2579,
+ 2626, 2632, 2649, 2959, 3071, 3107, 3223, 3331, 3395, 3415, 3548, 3641, 3675, 3703, 3820, 3825, 3849,
+ 3853, 3865, 3916, 45, 107, 110, 151, 168, 169, 247, 305, 313, 323, 357, 361, 777, 785,
+ 841, 1096, 1123, 1347, 1427, 1498, 1555, 1617, 1643, 1646, 1651, 1774, 2051, 2087, 2265, 2296, 2371,
+ 2971, 3022, 3241, 3287, 3319, 3331, 3543, 3601, 3683, 3689, 3697, 122, 259, 274, 387, 401, 496,
+ 657, 707, 739, 850, 857, 928, 929, 932, 996, 1123, 1270, 1303, 1609, 2151, 2193, 2371, 2632,
+ 2633, 55, 119, 291, 299, 343, 681, 1001, 1307, 1427, 1609, 1646, 1683, 2157, 2222, 3331, 4060
+};
+
+
+/* Q11 quntized LF+HF tables as already available in existing 10ms BASOP */
+const LC3_INT16 st1SCF0_7_base5_32x8_Q11[8 * 32] = {
+ 4634 , 1666, -1086, -2778, -3276, -2951, -2343, -1547, 6032,
+ 4939 , 1967, -908, -2517, -3186, -3066, -2287,
+ -4477, -4038, -3660, -3929, -3674, -2780, -1445, -98,
+ 1421, 1957, 1178, -235, -1323, -1950, -2200, -1553,
+ -2657, -1516, -707, -642, -825, -762, -160, 199,
+ 1873, 3570, 3910, 3162, 2239, 1326, 74, -608,
+ -5149, -5922, -4105, -1538, 904, 2462, 2719, 2500,
+ -1889, 1295, 2227, 1246, 269, -607, -424, 276,
+ 1619, 1287, 805, 983, 917, 430, 13, -176, 2965, 5579, 4733, 1915, -563, -1847, -1927, -1298,
+ 1625, 29, -1163, -1341, -982, -356, 139, 604, 5579, 6061, 3788, 1154, 287, 737, 1412, 1310,
+ -1087, -436, 12, 870, 969, 1759, 2439, 2040, 3456, 4989, 4772, 3645, 2958, 3113, 3015, 2002,
+ -6045, -3264, -225, 796, 1050, 1286, 1685, 1794, 209, 1208, 1268, 2595, 4955, 4612, 1078, -812,
+ 5494, 2718, 267, -693, -754, -393, -317, -480, 9886, 6389, 2857, 513, -806, -1318, -1316, -1481,
+ 180, -1167, -2345, -3420, -3779, -3204, -2289, -1094, 2849, 4058, 2279, -451, -1587, -1217, 280, 1676,
+ 788, -329, -1105, -1084, 390, 5244, 5773, 1345, 3957, 6165, 6278, 5122, 3954, 1172, -1662, -2409,
+ 359, -1537, -2129, -2326, -2134, -31, 4240, 7024, -2433, 751, 2682, 3447, 2562, 1930, 1692, 901,
+ 5188, 4327, 2586, 1560, 1069, 243, -926, -1434, 8190, 8354, 5781, 3535, 1325, -678, -1811, -2308,
+ 1040, 3253, 3541, 2062, 772, 976, 2227, 2227, 6489, 6673, 4961, 3675, 3117, 2400, 1002, -128,
+ 3879, 2562, 1209, 1246, 1798, 2292, 2086, 1271, 1943, 4367, 5578, 5673, 5208, 4138, 1700, -56,
+ -3851, -2589, 638, 3762, 4621, 4195, 4496, 4150, 505, 1957, 3114, 4048, 3974, 4575, 4072, 2606 };
+
+const LC3_INT16 st1SCF8_15_base5_32x8_Q11[8 * 32] = {
+ 475, -2066, -4387, -4865, -4568, -4456, -4691, -5187, -2652, -3685, -3865, -3707, -3611, -3756, -3696, -3557,
+ 285, -529, -1333, -2188, -3316, -4480, -5402, -6101, -648, -978, -1129, -993, -488, -293, 140, 181,
+ 1801, 611, -1875, -4519, -5614, -5860, -5915, -6045, -608, -1997, -2782, -2015, -1337, -2027, -3307, -4930,
+ 698, 551, 115, 102, -195, -1557, -4767, -7724, -2892, -3042, -2429, -1280, 315, 1180, 1628, 1222,
+ -469, -683, -1657, -3350, -3860, -3369, -2878, -3004, -2194, -2903, -3172, -2976, -2113, -1414, -878, -1014,
+ -1210, -146, 708, 616, -2291, -4999, -4564, -3881, -1738, -1194, 184, 1731, 2183, 1511, 525, -1008,
+ 2336, 1974, 781, -989, -3720, -5740, -6623, -7084, -771, 87, 1058, 516, -443, -1094, -1312, -1781,
+ 1362, 2249, 2833, 2751, 1685, 442, -829, -2192, -1692, -1375, -468, 1063, 2800, 4465, 5194, 4508,
+ 2888, 1545, -2674, -3832, -2540, -2595, -4171, -5933, 740, -45, -1187, -1801, -1742, -1596, -1500, -1819,
+ 896, 626, -15, -1015, -1652, -2507, -3485, -4598, 1327, 1397, 519, 151, 644, 481, 296, -140,
+ 2292, 2529, 1207, -2810, -4856, -4112, -3414, -3945, 291, -227, -579, -14, 586, 94, -1234, -4640,
+ 1032, 1694, 2293, 2415, 2212, 1429, -1869, -7325, -1026, -667, 58, 537, 738, 1302, 1964, 2678,
+ 7679, 3120, -937, -1636, -792, -770, -1347, -2625, -2361, -2269, -1152, -452, -716, -1543, -2025, -2638,
+ 2106, 2248, 1574, 422, -702, -1546, -2134, -3079, 264, 1412, 2301, 2682, 2775, 2915, 2370, 832,
+ 2745, 2847, 2140, 1302, -563, -3173, -5002, -6194, 4380, 8698, 5934, 1910, -600, -1660, -1616, -1916,
+ 1157, 3260, 4911, 6220, 5456, 2853, 827, -1344, -865, 668, 2850, 4570, 5349, 5459, 4917, 3603
+};
+
+
+/* harmonically trained st1C with pitch info */
+/* Q11 values, to enable BE in synthesis */
+/* st1C mean for pitch_rx==0 && ltpf_rx==* */
+const LC3_FLOAT lrsns_st1C_pitch0_mp0Q11[16] = {
++1.119628906250000e+00f, +1.270507812500000e+00f, +9.570312500000000e-01f, +5.668945312500000e-01f, +4.296875000000000e-01f, +2.036132812500000e-01f, +1.660156250000000e-02f, -8.251953125000000e-02f,
+-1.796875000000000e-01f, -2.641601562500000e-01f, -2.949218750000000e-01f, -1.552734375000000e-01f, -1.401367187500000e-01f, -4.677734375000000e-01f, -1.143066406250000e+00f, -1.835449218750000e+00f
+};
+
+/* st1C mean for pitch_rx==1 && ltpf_rx==0 */
+float lrsns_st1C_pitch1_mp1Q11[16] = {
++1.259765625000000e-01f, +3.930664062500000e-01f, +3.852539062500000e-01f, +2.602539062500000e-01f, +2.475585937500000e-01f, +6.005859375000000e-02f, +8.935546875000000e-02f, +7.568359375000000e-02f,
++4.296875000000000e-02f, +7.373046875000000e-02f, +2.612304687500000e-01f, +4.975585937500000e-01f, +4.995117187500000e-01f, +2.832031250000000e-02f, -9.829101562500000e-01f, -2.056152343750000e+00f
+};
+
+#ifdef LRSNS_CBC_NO_LTPF_DEPENDENCY
+/* lrsns_st1C_Both_fullTableResWord8 */
+const LC3_FLOAT* lrsns_st1CTrainedMapMeans[2] = { lrsns_st1C_pitch0_mp0Q11 ,lrsns_st1C_pitch1_mp1Q11 };
+#else
+/* st1C mean for pitch_rx==1 && ltpf_rx==1 */
+const LC3_FLOAT lrsns_st1C_pitch2_mp2Q11[16] = {
+-2.055664062500000e-01f, +1.005859375000000e-01f, +1.948242187500000e-01f, +1.577148437500000e-01f, +1.870117187500000e-01f, +1.220703125000000e-02f, +1.137695312500000e-01f, +1.284179687500000e-01f,
++1.171875000000000e-01f, +1.860351562500000e-01f, +4.462890625000000e-01f, +7.148437500000000e-01f, +7.128906250000000e-01f, +1.938476562500000e-01f, -9.296875000000000e-01f, -2.129394531250000e+00f
+};
+
+/* lrsns_st1C_Both_fullTableResWord8 */
+const LC3_FLOAT* lrsns_st1CTrainedMapMeans[3] = { lrsns_st1C_pitch0_mp0Q11 ,lrsns_st1C_pitch1_mp1Q11,lrsns_st1C_pitch2_mp2Q11 };
+#endif
+/* float tables BE representable in Q11 after Q4*Q7 multiplication */
+const LC3_FLOAT lrsns_st1C_Both_scaleQ4_7p4bits[2] = {
++5.375f, +86.0 /* exact BASOP Q4 value, used in synthesis */
+};
+const LC3_FLOAT lrsns_st1C_Both_inv_scaleQ15_7p4bits[2] = {
++1.860351562500000e-01f , +6096.0 /* BASOP Q15 value, invScale used in encoder side for target creation */
+};
+
+/* BASOP table for stage1C BE representable in Q11 after Q4*Q7 multiplication */
+const LC3_INT16 lrsns_st1C_Both_scaleQ4_7p4bits_fx[2] = {
+-1, 86 /* exact BASOP Q4 value, used in synthesis */
+};
+const LC3_INT16 lrsns_st1C_Both_inv_scaleQ15_7p4bits_fx[2] = {
+-1 , 6096 /* BASOP Q15 value, invScale used in encoder side target creation */
+};
+
+/* Word8 storage of ST1 C codebook to save ROM in BASOP */
+const LC3_INT8 lrsns_st1C_Both_Word8[170 * 16] = {
+ -88, -78, -57, -39, -27, -15, -6, 3, 11, 17, 20, 23, 32, 47, 69, 88,
+ -86, -40, -7, 4, 1, 5, 10, 10, 0, -5, -5, 4, 9, 23, 38, 39,
+ -71, -69, -65, -49, -29, -5, 16, 30, 21, -8, -3, 15, 27, 40, 63, 87,
+ -71, -36, -10, -5, 2, 17, 15, 18, 24, 24, 13, 7, 11, 2, -6, -7,
+ -70, -23, 13, 12, 0, 7, 19, 14, 1, -1, 6, 3, -2, 1, 9, 13,
+ -68, -79, -67, -42, -26, -17, 8, 29, 38, 34, 32, 33, 32, 36, 36, 21,
+ -62, -66, -56, -41, -33, -13, 11, 17, 16, 17, 28, 39, 40, 41, 40, 23,
+ -61, -62, -51, -31, -26, -25, -23, -15, -3, 12, 24, 30, 33, 43, 68, 85,
+ -60, -63, -47, -28, -17, -9, 13, 30, 36, 31, 25, 24, 27, 28, 17, -6,
+ -57, -47, -25, -11, -17, -12, -1, -7, -4, -1, -7, 1, 23, 44, 58, 60,
+ -54, -59, -61, -50, -22, -1, 25, 37, 37, 31, 21, 13, 21, 31, 27, 4,
+ -53, -36, -14, 3, 13, 12, 14, 19, 26, 31, 30, 22, 3, -12, -21, -36,
+ -53, -52, -39, -24, -12, 2, 23, 34, 32, 27, 16, 8, 11, 21, 14, -9,
+ -45, -46, -31, -16, -8, -5, 6, 21, 31, 32, 26, 22, 18, 11, 1, -17,
+ -40, -11, 7, 11, 4, 13, 5, -13, -28, -20, -10, 0, 8, 19, 23, 32,
+ -40, -32, -18, -2, 6, 12, 8, 1, 2, 4, 9, 15, 20, 13, 3, -1,
+ -40, -9, 11, 7, 6, 6, 0, -13, -13, -1, 7, 12, 8, 4, 6, 9,
+ -39, 5, 19, 12, 13, 9, 4, 3, -2, -6, -4, 2, 3, -2, -6, -13,
+ -38, -13, 1, 1, 4, 17, 16, 12, 8, 0, -9, -23, -20, 0, 18, 24,
+ -38, -25, -13, -12, -24, -17, -6, 4, 10, 6, -17, -13, 6, 35, 51, 53,
+ -38, -34, -30, -24, -9, 7, 17, 18, 14, 9, 11, 14, 18, 18, 12, -3,
+ -38, -36, -19, 2, 20, 28, 28, 33, 31, 16, 6, 4, -4, -12, -23, -36,
+ -38, -46, -38, -22, -17, -22, -11, 18, 35, 34, 27, 25, 24, 22, 12, -3,
+ -37, 3, 34, 16, -8, -30, -54, -45, -23, -9, -3, 14, 12, 15, 42, 72,
+ -35, -55, -53, -38, -30, -20, -5, 6, 13, 16, 21, 25, 29, 41, 48, 36,
+ -35, -45, -50, -47, -48, -41, -31, -16, -1, 9, 20, 21, 29, 51, 81, 104,
+ -35, -46, -46, -35, -24, -11, 9, 27, 34, 33, 27, 25, 21, 17, 9, -6,
+ -34, -24, -20, -13, -11, -7, 2, 2, -13, -4, 23, 31, 21, 16, 16, 16,
+ -33, -54, -66, -58, -43, -23, -16, -10, 1, 18, 23, 18, 28, 51, 74, 89,
+ -31, 16, 51, 48, 30, 18, 12, 2, -7, -17, -23, -26, -29, -26, -17, -1,
+ -31, -20, -18, -20, -13, -8, 1, 13, 20, 2, -13, -8, 12, 27, 31, 25,
+ -30, -33, -40, -36, -30, -11, 3, 10, 14, 15, 24, 29, 31, 27, 20, 8,
+ -30, -45, -40, -20, -14, -21, -31, -23, -10, 1, 12, 15, 22, 39, 64, 83,
+ -29, -15, 0, 4, 8, 16, 17, 11, 5, 4, 2, 1, 11, 7, -13, -29,
+ -29, -29, -20, -3, 15, 27, 27, 18, 17, 29, 31, 19, -3, -19, -35, -44,
+ -28, -21, -26, -26, 2, 22, 30, 37, 34, 18, 8, 2, 0, -9, -18, -25,
+ -28, -19, -11, -7, -1, 8, 13, 17, 21, 25, 30, 23, 5, -9, -26, -42,
+ -27, -9, 3, 2, 3, 11, -7, -14, 9, 25, 14, -6, -4, -1, 0, 2,
+ -27, -27, -25, -17, -18, -10, -8, -16, -18, 1, 16, 20, 29, 35, 38, 27,
+ -26, -44, -8, 8, -12, -5, -6, -9, 1, 13, 17, 15, 35, 42, 6, -29,
+ -24, -22, -16, -13, -12, 0, 10, 15, 19, 8, 5, 13, 26, 18, -5, -21,
+ -24, -42, -47, -33, -31, -32, -19, 2, 13, 13, 9, 4, 16, 35, 58, 80,
+ -24, -16, -7, -4, -7, -6, -8, -9, -3, 5, 11, 15, 23, 22, 12, -2,
+ -23, -13, 1, 1, -19, -17, 7, 21, 29, 29, 20, 12, 0, -9, -15, -26,
+ -23, -39, -40, -26, -19, -13, -4, -10, -21, -20, 0, 18, 26, 39, 57, 73,
+ -22, -26, -25, -25, -28, -21, -3, 23, 35, 38, 31, 20, 10, 5, 2, -13,
+ -21, 3, 27, 20, -9, -8, 4, 3, -3, -10, -18, -16, -4, 8, 11, 13,
+ -21, -13, -5, 1, 15, 22, 23, 27, 31, 25, 13, -1, -18, -28, -33, -40,
+ -20, -15, 0, 10, 9, 13, 12, 0, -15, -8, 7, 9, 4, 0, -2, -6,
+ -20, -15, -9, -6, -2, -14, -40, -5, 34, 49, 45, 29, -7, -16, -7, -18,
+ -19, 13, 24, 22, 27, 17, 2, -1, -8, -17, -26, -16, 0, 1, -4, -15,
+ -18, -14, -7, 6, 19, 21, 20, 22, 20, 16, 17, 14, -5, -27, -39, -44,
+ -17, 30, 76, 76, 57, 44, 11, -23, -43, -54, -57, -58, -53, -33, 5, 40,
+ -17, -19, -22, -34, -39, -15, 12, 23, 21, 17, 18, 22, 20, 13, 6, -7,
+ -17, -12, -8, 6, 19, 4, -15, 0, 21, 32, 30, 8, -9, -15, -20, -24,
+ -16, 33, 77, 82, 55, 23, -2, -11, -20, -39, -58, -65, -58, -33, 0, 32,
+ -16, -21, -26, -21, -7, 7, 10, 8, 11, 16, 22, 20, 12, 3, -4, -16,
+ -15, 8, 29, 23, 11, -9, -29, -23, -14, -5, -2, -2, 4, 10, 9, 3,
+ -14, -17, -19, -22, -11, 2, 15, 27, 33, 27, 20, 14, 3, -10, -20, -27,
+ -13, -2, 6, 3, -7, -7, 4, 26, 31, 19, 13, 12, -4, -23, -29, -32,
+ -13, -6, 6, 18, 21, 18, 12, 7, 5, 5, 5, -1, -7, -15, -23, -33,
+ -12, -7, 0, 3, 5, 0, -5, 4, 18, 24, 25, 16, 1, -13, -25, -34,
+ -12, -3, 0, -4, -3, 10, 9, -3, -5, -6, -6, -3, 14, 20, 5, -14,
+ -12, -11, -15, -14, -7, 2, 12, 6, -10, -21, -4, 11, 22, 22, 15, 4,
+ -11, -12, -13, -5, 11, 16, 11, 6, 5, 15, 22, 20, 3, -12, -23, -33,
+ -11, -10, -8, -11, -3, 13, 19, 18, 11, -1, -12, -8, 6, 7, 0, -12,
+ -11, -17, -20, -20, -16, -9, -2, 7, 24, 32, 32, 26, 14, 0, -14, -27,
+ -10, -11, -11, -20, -26, -25, -7, 7, 20, 29, 19, 6, 5, 15, 9, 0,
+ -10, -5, -7, -9, -4, 9, 10, 0, -17, -28, -21, -7, 12, 28, 29, 22,
+ -8, -20, -30, -25, -28, -26, -18, -9, 7, 15, 24, 26, 30, 33, 24, 5,
+ -8, -17, -19, -17, -16, -7, -7, -7, 3, 4, 4, 6, 21, 28, 22, 10,
+ -8, 35, 62, 60, 43, 21, 6, -4, -21, -34, -37, -42, -43, -32, -12, 6,
+ -8, -6, -3, -1, 1, 0, -5, -5, 2, 11, 23, 21, 8, -2, -11, -24,
+ -7, -21, -21, -13, 1, 18, 28, 30, 30, 34, 33, 18, 0, -21, -52, -57,
+ -6, -31, -40, -39, -36, -27, -20, -22, -19, -4, 10, 12, 19, 38, 69, 95,
+ -6, -38, -48, -42, -37, -27, -13, 2, 7, 9, 17, 23, 33, 45, 46, 28,
+ -6, -18, -39, -58, -59, -34, -15, -6, 0, 4, 15, 22, 24, 38, 59, 71,
+ -4, 6, 6, 11, 15, 9, 1, -7, 2, 11, 16, 10, -5, -14, -26, -31,
+ -4, 2, 7, -6, -59, -49, -4, -1, 1, 15, 9, -19, -19, 11, 52, 64,
+ -2, 31, 53, 43, 20, 8, -2, -17, -24, -21, -22, -25, -22, -14, -8, 1,
+ 1, -3, -3, 4, 6, 9, -4, -31, -39, -17, -5, -1, 6, 16, 27, 34,
+ 1, 10, 15, 12, -5, -20, -21, -10, 12, 27, 23, 10, -4, -12, -17, -23,
+ 3, 13, 23, 25, 20, 14, 3, 7, 11, -4, -31, -43, -35, -21, -1, 19,
+ 3, -3, -9, -16, -19, -7, 1, 7, 11, -2, -5, 5, 23, 20, 2, -10,
+ 4, -22, -27, -23, -23, -11, 7, 14, 15, 15, 6, -3, -9, -6, 19, 44,
+ 5, -5, -9, -8, -9, -7, 0, 17, 29, 22, 12, 12, 6, -8, -23, -32,
+ 6, -31, -58, -64, -41, -12, -1, 3, 2, 0, 3, 6, 21, 37, 55, 74,
+ 7, 12, 10, 1, 2, 6, 2, -5, -7, -3, -2, 0, 1, 1, -6, -19,
+ 9, 1, 2, 12, 15, 11, -11, -33, -17, 13, 20, 9, 0, -7, -11, -13,
+ 10, 21, 26, 24, 18, 4, -5, -13, -14, -6, 4, 7, -7, -19, -25, -25,
+ 11, 1, -4, -7, -17, -28, -18, 4, 19, 27, 21, 12, 6, 2, -8, -20,
+ 11, 4, -17, -36, -48, -39, -18, 0, 3, 1, 3, 6, 15, 27, 39, 49,
+ 11, 3, -12, -26, -20, -2, 11, 16, 14, 9, 18, 19, 6, -7, -15, -25,
+ 12, 0, -12, -7, -5, -15, -21, -14, -5, 4, 13, 22, 22, 13, 3, -8,
+ 14, 17, 19, 17, 17, 16, 1, -9, -8, -5, -13, -11, -6, -7, -14, -27,
+ 14, 33, 52, 50, 32, 12, -1, -6, -8, -14, -23, -30, -36, -35, -26, -13,
+ 16, 11, 10, 15, 21, 13, 13, 10, 8, 4, 6, 6, -6, -25, -50, -52,
+ 17, 9, 9, 23, 23, 10, 5, 16, 20, 13, 2, -18, -35, -39, -30, -23,
+ 17, 31, 47, 49, 42, 32, 22, 8, -7, -21, -31, -30, -43, -53, -42, -21,
+ 19, 37, 50, 42, 28, 24, 15, -8, -22, -22, -19, -28, -39, -39, -26, -12,
+ 19, 39, 47, 31, 10, 0, 1, 1, -6, -15, -21, -23, -26, -25, -18, -13,
+ 19, 12, 0, -7, -3, 1, -2, -12, -19, -19, -11, -1, 9, 14, 12, 5,
+ 19, 33, 47, 55, 47, 23, -6, -18, -23, -24, -14, -9, -22, -34, -42, -33,
+ 19, 13, -1, -20, -24, -13, -6, -6, -11, -16, -21, -24, -15, 9, 45, 71,
+ 21, 15, 8, 4, 5, 6, 3, 4, -2, -17, -20, -8, 12, 9, -12, -28,
+ 22, 10, 9, 20, 18, -4, -6, 1, 5, 9, 16, 18, -1, -22, -47, -48,
+ 22, 22, 27, 42, 41, 33, 21, 0, -17, -27, -28, -37, -39, -32, -19, -8,
+ 23, 4, -28, -27, -16, -5, 9, 28, 28, 0, -52, -61, -12, 18, 35, 56,
+ 23, -6, -26, -22, -18, -18, -20, -28, -23, -3, 9, 3, 1, 17, 44, 66,
+ 23, 21, 12, 10, 6, -5, 3, 8, 4, -1, 8, 11, -2, -16, -40, -43,
+ 24, 11, -4, -9, -8, -10, -21, -37, -44, -26, 0, 8, 17, 29, 36, 35,
+ 25, 11, 3, 7, 13, 14, 9, 2, -7, -13, -17, -12, -10, -10, -7, -8,
+ 25, 24, 17, 12, 20, 7, -11, -10, -15, -16, -16, -5, 3, -4, -11, -21,
+ 27, 26, 17, 6, -5, -16, -12, 2, -1, -9, -16, -7, 3, 3, -2, -15,
+ 28, 15, -10, -29, -30, -17, 4, 16, 33, 29, 15, 6, -5, -18, -18, -18,
+ 28, 12, 4, 16, 23, 12, 6, -1, -6, -7, 2, 8, -2, -19, -38, -37,
+ 29, 16, -1, -15, -25, -15, -12, -9, 18, 29, 23, 12, -1, -13, -16, -20,
+ 29, 28, 25, 33, 32, 6, -13, -20, -8, 4, 7, 0, -14, -25, -43, -40,
+ 29, 25, 19, 17, 20, 8, -12, -34, -34, -19, -14, -6, 2, 4, 3, -9,
+ 30, 28, 22, 14, 17, 16, 15, 8, -5, -19, -13, -4, -7, -20, -40, -41,
+ 30, 1, -20, -4, -6, -32, -37, -28, -18, -11, -7, -3, 8, 21, 44, 63,
+ 30, 42, 57, 45, 22, 6, 8, 2, -10, -27, -43, -50, -45, -33, -13, 9,
+ 32, 25, 20, 24, 23, 6, 3, -2, -10, -8, 4, 8, -8, -27, -47, -45,
+ 32, 40, 44, 29, 12, 0, -10, -18, -24, -20, -18, -23, -25, -19, -5, 4,
+ 34, 45, 56, 51, 33, 16, 10, 6, -8, -21, -25, -42, -55, -52, -33, -16,
+ 34, 53, 63, 61, 58, 44, 12, -26, -62, -68, -60, -61, -47, -18, 9, 9,
+ 34, 28, 22, 17, 16, 16, 9, 0, -6, -12, -26, -31, -21, -13, -13, -19,
+ 34, 23, 10, -15, -33, -24, -17, -15, -7, 0, -5, -10, -4, 5, 23, 35,
+ 35, 23, 12, 0, -16, -22, -17, 0, 17, 19, 14, 7, -5, -16, -24, -27,
+ 35, 32, -23, -51, -12, 33, 23, 0, -10, 1, -12, -29, -13, 9, 17, 0,
+ 36, 69, 78, 62, 30, -9, -40, -49, -49, -44, -48, -51, -37, -10, 19, 44,
+ 36, 21, 8, 11, 18, 8, 9, 8, 7, 3, 2, 1, -13, -28, -46, -44,
+ 37, 27, 11, 6, 14, 5, -6, -1, -9, -26, -37, -18, 3, 5, 0, -11,
+ 39, 31, 20, 13, 12, 6, -8, -12, -16, -16, -22, -18, -9, -6, -5, -10,
+ 39, 33, 25, 21, 22, 18, 7, -4, -24, -33, -33, -20, -9, -8, -14, -22,
+ 39, 52, 61, 57, 40, 27, 9, -12, -27, -37, -46, -50, -48, -40, -23, -2,
+ 40, 31, 20, 18, 14, -8, -5, 4, 8, 4, -1, -2, -14, -28, -42, -38,
+ 40, 29, 17, 19, 15, -9, -20, -18, -7, 1, 10, 9, -5, -15, -33, -33,
+ 41, 33, 23, 18, 20, 2, -13, -6, -6, -9, -16, -13, -12, -18, -21, -21,
+ 41, 58, 71, 51, 33, 19, -13, -42, -56, -58, -65, -67, -53, -17, 32, 65,
+ 41, 31, 15, 10, 4, -16, -7, 5, 7, 8, 12, 8, -7, -26, -44, -40,
+ 43, 40, 28, 23, 23, 6, -13, -20, -26, -18, -2, 3, -2, -13, -34, -36,
+ 43, 23, -11, -15, 2, 3, 6, 5, 3, 4, 11, 11, -2, -17, -33, -32,
+ 43, 54, 61, 49, 24, -1, -8, -3, -8, -21, -32, -43, -46, -39, -21, -9,
+ 43, 30, 9, -8, -2, 0, -10, -12, -14, -12, -12, -2, 4, 2, -3, -14,
+ 43, 35, 23, 15, 12, -8, -33, -27, -16, -12, -14, -4, 5, 0, -6, -13,
+ 44, 31, 19, 12, 4, -5, 1, -1, -10, -14, -1, 5, -3, -15, -33, -34,
+ 44, 28, 8, 8, 18, 13, 7, -3, -10, -8, -3, -3, -13, -23, -33, -31,
+ 46, 40, 9, -22, -17, 6, 18, 19, 6, -11, -14, -5, 5, -9, -35, -35,
+ 47, 47, 53, 51, 27, -3, -46, -65, -46, -33, -32, -29, -28, -17, 17, 56,
+ 47, 43, 27, 25, 24, 2, -2, -1, -17, -19, -1, 6, -11, -33, -50, -40,
+ 48, 50, 47, 34, 9, -7, -10, -9, -10, -12, -17, -28, -33, -30, -19, -12,
+ 48, 51, 51, 41, 25, 7, -18, -39, -47, -47, -44, -36, -21, -2, 14, 17,
+ 48, 23, -3, 10, 21, -2, -9, -6, -4, -2, 8, 15, 0, -23, -40, -36,
+ 50, 25, 2, -3, 4, 16, 13, -4, -21, -30, -30, -29, -20, -2, 13, 17,
+ 59, 44, 18, 13, 23, 18, 8, -7, -28, -26, -8, -3, -10, -24, -42, -35,
+ 61, 47, 30, 22, 25, 21, 8, -2, -16, -25, -14, -5, -15, -39, -56, -43,
+ 62, 46, 31, 37, 38, 16, -13, -33, -25, -7, -1, -3, -20, -39, -51, -38,
+ 63, 47, 23, 9, 5, -2, -13, -12, -8, -7, -14, -20, -26, -25, -15, -6,
+ 63, 42, 20, 9, 7, 0, -10, -18, -21, -22, -24, -24, -22, -16, 0, 17,
+ 64, 54, 43, 22, -17, -38, -42, -38, -37, -23, -17, -20, -15, -2, 22, 42,
+ 64, 51, 36, 34, 35, 21, 6, -9, -34, -41, -20, -7, -18, -35, -48, -36,
+ 66, 66, 65, 55, 35, 8, -9, -18, -29, -35, -39, -45, -47, -39, -24, -9,
+ 67, 38, -11, -47, -53, -27, -14, -19, -21, -21, 0, 6, 9, 19, 31, 45,
+ 70, 60, 50, 45, 32, 3, -17, -33, -34, -24, -10, -9, -22, -36, -44, -30,
+ 75, 57, 34, 30, 34, 20, -7, -29, -42, -36, -21, -15, -19, -28, -32, -20,
+ 76, 61, 27, -11, -30, -32, -29, -24, -24, -22, -18, -21, -16, 1, 22, 42,
+ 96, 77, 40, 5, -17, -27, -30, -28, -25, -24, -22, -23, -23, -16, 1, 16,
+ 99, 86, 61, 28, -5, -26, -39, -35, -34, -20, -5, -15, -34, -40, -22, 2,
+ 127, 101, 43, -12, -35, -34, -40, -42, -40, -40, -41, -40, -31, -6, 28, 61
+};
+#endif /* 1.25ms LRSNS */
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+
+const LC3_FLOAT lrsns_gains_Q11[3][8] = {
+ { +1.8125 , +2.5 ,+3.3125, +4.3125, 0.0, 0.0, 0.0, 0.0}, /*4 splitLF Q11 */
+ { +1.4375 , +1.8125 , +2.125 , +2.5 , +2.9375 , +3.5 , +4.0625 , +4.9375 }, /*8 full Q11 */
+ { +1.375 , +1.75 , +2.0 , +2.3125 , +2.625 , +3.0625 , +3.5625 , +4.4375 } /*8 fix-env Q11 */
+};
+
+
+/* BASOP optimized fixenv tables */
+const LC3_INT16 env_Qs[SNSLR_N_FIXENV] = { 4, 4 , 4, 4 }; /* Q values for fix0 .. fix3 env searchrepresentation */
+const LC3_FLOAT env_Qscale[SNSLR_N_FIXENV] = { 1.0 / 16.0, 1.0 / 16.0 , 1.0 / 16.0,1.0 / 16.0 }; /* Qscaling values for fix0 .. fix3 env searchrepresentation */
+
+
+const LC3_INT16 signs_fix[SNSLR_N_FIXENV] = { 12, 12, 12, 10 };
+
+const LC3_INT32 long_bell[M - 1 + 4] = {
+ 6, 6, 7, 7, 8 ,
+ 8, 8, 7, 7, 6 ,
+ 6, 5, 5, 5, 5 ,
+ 5, 5, 5, 5 };
+
+const LC3_INT32 decay[M - 1] = { /* floor((25:-1:11 -i)/2)*/
+ 12,12,11,11,10,
+ 10, 9, 9, 8, 8,
+ 7, 7, 6, 6, 5 };
+
+const LC3_INT32* env_ptrs[4] = { &(long_bell[4]), decay, &(long_bell[2]), long_bell };
+
+
+const LC3_FLOAT shift_en_norm_factors[SNSLR_N_FIXENV][SNSLR_N_FIXENV_SHIFTS] =
+{ /* shift0, shift1, shift2, shift3 */
+ /*12x init_bellamps , 1/sqrt( ), 1.0 / sqrt( ), 1.0 / sqrt( ), 1/sqrt( ) */
+ {1485.0 / 32768.0, 1548.0 / 32768.0, 1620.0 / 32768.0, 1704.0 / 32768.0 } ,
+
+ /*12*decay: 1/sqrt( ), 1.0 / sqrt( ), 1.0 / sqrt( ),*/
+ {980.0 / 32768.0 , 1031.0 / 32768.0 , 1091.0 / 32768.0 , 1154.0 / 32768.0},
+
+
+ /*12x start bellamps , 1/sqrt( ), 1.0 / sqrt( ), 1.0 / sqrt( ), 1/sqrt( ) */
+ { 1417.0 / 32768.0 , 1450.0 / 32768.0 , 1485.0 / 32768.0 , 1548.0 / 32768.0 },
+
+
+ /*10x early_bellamps , 1/sqrt( ), 1.0 / sqrt( ), 1.0 / sqrt( ), 1/sqrt( ) */
+ {1471.0 / 32768.0 , 1471.0 / 32768.0 , 1488.0 / 32768.0 , 1526.0 / 32768.0 } ,
+};
+
+#endif
+
+#ifdef CR9_C_ADD_1p25MS
+
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+const LC3_INT16 lrsns_ltp_bits[8] = {
+ 2, /*00(x=0) , ltp=0 ltpf=0 x is next param */
+ 2, /*00(x=1) x is next param */
+ 3 + 4, /*010 ltp=1 ltpf=0, phaseA or PhaseB(phaseB with reduced resolution) */
+ 3 + 4, /*011 ltp=1 ltpf=0, PhaseB(phaseB with reduced resolution) */
+ 2 + 4, /*10(x=0) ltp=1 ltpf=1, phase A , +extra bit */
+ 2 + 4, /*10(x=1) */
+ 2 + 5, /*11(x=0) ltp=1 ltpf=1, phase B , +extra bit */
+ 2 + 5 /*11(x=1) */
+};
+#endif
+
+
+const LC3_FLOAT MDCT_WINDOW_80_1_25ms[20] = {
+ 0.078459095727845,
+ 0.233445363855905,
+ 0.382683432365090,
+ 0.522498564715949,
+ 0.649448048330184,
+ 0.760405965600031,
+ 0.852640164354092,
+ 0.923879532511287,
+ 0.972369920397677,
+ 0.996917333733128,
+ 0.996917333733128,
+ 0.972369920397677,
+ 0.923879532511287,
+ 0.852640164354092,
+ 0.760405965600031,
+ 0.649448048330184,
+ 0.522498564715949,
+ 0.382683432365090,
+ 0.233445363855906,
+ 0.078459095727845
+};
+
+const LC3_FLOAT MDCT_WINDOW_160_1_25ms[40] = {
+ 0.039259815759069,
+ 0.117537397457838,
+ 0.195090322016128,
+ 0.271440449865074,
+ 0.346117057077493,
+ 0.418659737537428,
+ 0.488621241496955,
+ 0.555570233019602,
+ 0.619093949309834,
+ 0.678800745532942,
+ 0.734322509435686,
+ 0.785316930880745,
+ 0.831469612302545,
+ 0.872496007072797,
+ 0.908143173825081,
+ 0.938191335922484,
+ 0.962455236453647,
+ 0.980785280403230,
+ 0.993068456954926,
+ 0.999229036240723,
+ 0.999229036240723,
+ 0.993068456954926,
+ 0.980785280403230,
+ 0.962455236453647,
+ 0.938191335922484,
+ 0.908143173825081,
+ 0.872496007072797,
+ 0.831469612302545,
+ 0.785316930880745,
+ 0.734322509435686,
+ 0.678800745532942,
+ 0.619093949309834,
+ 0.555570233019603,
+ 0.488621241496955,
+ 0.418659737537428,
+ 0.346117057077493,
+ 0.271440449865075,
+ 0.195090322016129,
+ 0.117537397457838,
+ 0.039259815759069
+};
+
+const LC3_FLOAT MDCT_WINDOW_240_1_25ms[60] = {
+ 0.026176948307873,
+ 0.078459095727845,
+ 0.130526192220052,
+ 0.182235525492147,
+ 0.233445363855905,
+ 0.284015344703923,
+ 0.333806859233771,
+ 0.382683432365090,
+ 0.430511096808295,
+ 0.477158760259608,
+ 0.522498564715949,
+ 0.566406236924833,
+ 0.608761429008721,
+ 0.649448048330184,
+ 0.688354575693754,
+ 0.725374371012288,
+ 0.760405965600031,
+ 0.793353340291235,
+ 0.824126188622016,
+ 0.852640164354092,
+ 0.878817112661965,
+ 0.902585284349861,
+ 0.923879532511287,
+ 0.942641491092178,
+ 0.958819734868193,
+ 0.972369920397677,
+ 0.983254907563955,
+ 0.991444861373810,
+ 0.996917333733128,
+ 0.999657324975557,
+ 0.999657324975557,
+ 0.996917333733128,
+ 0.991444861373810,
+ 0.983254907563955,
+ 0.972369920397677,
+ 0.958819734868193,
+ 0.942641491092178,
+ 0.923879532511287,
+ 0.902585284349861,
+ 0.878817112661965,
+ 0.852640164354092,
+ 0.824126188622015,
+ 0.793353340291235,
+ 0.760405965600031,
+ 0.725374371012288,
+ 0.688354575693754,
+ 0.649448048330184,
+ 0.608761429008720,
+ 0.566406236924833,
+ 0.522498564715949,
+ 0.477158760259609,
+ 0.430511096808296,
+ 0.382683432365090,
+ 0.333806859233771,
+ 0.284015344703923,
+ 0.233445363855906,
+ 0.182235525492148,
+ 0.130526192220052,
+ 0.078459095727845,
+ 0.026176948307873
+};
+
+const LC3_FLOAT MDCT_WINDOW_320_1_25ms[80] = {
+ 0.019633692460628,
+ 0.058870803651189,
+ 0.098017140329561,
+ 0.137012341681968,
+ 0.175796279934355,
+ 0.214309153065051,
+ 0.252491577015158,
+ 0.290284677254462,
+ 0.327630179561693,
+ 0.364470499879150,
+ 0.400748833103141,
+ 0.436409240673342,
+ 0.471396736825998,
+ 0.505657373377985,
+ 0.539138322911000,
+ 0.571787960227612,
+ 0.603555941953571,
+ 0.634393284163645,
+ 0.664252437911282,
+ 0.693087362545636,
+ 0.720853596702919,
+ 0.747508326862597,
+ 0.773010453362737,
+ 0.797320653772707,
+ 0.820401443525513,
+ 0.842217233716286,
+ 0.862734385977792,
+ 0.881921264348355,
+ 0.899748284052221,
+ 0.916187957117136,
+ 0.931214934758804,
+ 0.944806046466878,
+ 0.956940335732209,
+ 0.967599092360260,
+ 0.976765881320872,
+ 0.984426568089892,
+ 0.990569340443577,
+ 0.995184726672197,
+ 0.998265610184716,
+ 0.999807240482065,
+ 0.999807240482065,
+ 0.998265610184716,
+ 0.995184726672197,
+ 0.990569340443577,
+ 0.984426568089892,
+ 0.976765881320872,
+ 0.967599092360260,
+ 0.956940335732209,
+ 0.944806046466878,
+ 0.931214934758804,
+ 0.916187957117136,
+ 0.899748284052222,
+ 0.881921264348355,
+ 0.862734385977792,
+ 0.842217233716287,
+ 0.820401443525514,
+ 0.797320653772707,
+ 0.773010453362737,
+ 0.747508326862597,
+ 0.720853596702919,
+ 0.693087362545636,
+ 0.664252437911282,
+ 0.634393284163646,
+ 0.603555941953572,
+ 0.571787960227612,
+ 0.539138322911000,
+ 0.505657373377985,
+ 0.471396736825998,
+ 0.436409240673342,
+ 0.400748833103141,
+ 0.364470499879150,
+ 0.327630179561694,
+ 0.290284677254462,
+ 0.252491577015158,
+ 0.214309153065051,
+ 0.175796279934355,
+ 0.137012341681968,
+ 0.098017140329561,
+ 0.058870803651189,
+ 0.019633692460629
+};
+
+const LC3_FLOAT MDCT_WINDOW_480_1_25ms[120] = {
+ 0.013089595571344,
+ 0.039259815759069,
+ 0.065403129230143,
+ 0.091501618663402,
+ 0.117537397457838,
+ 0.143492621991179,
+ 0.169349503849025,
+ 0.195090322016128,
+ 0.220697435021501,
+ 0.246153293028993,
+ 0.271440449865074,
+ 0.296541574975571,
+ 0.321439465303162,
+ 0.346117057077493,
+ 0.370557437509836,
+ 0.394743856384267,
+ 0.418659737537428,
+ 0.442288690219001,
+ 0.465614520325111,
+ 0.488621241496955,
+ 0.511293086077052,
+ 0.533614515915611,
+ 0.555570233019602,
+ 0.577145190037234,
+ 0.598324600570659,
+ 0.619093949309834,
+ 0.639439001980585,
+ 0.659345815100069,
+ 0.678800745532942,
+ 0.697790459841680,
+ 0.716301943424654,
+ 0.734322509435686,
+ 0.751839807478977,
+ 0.768841832073459,
+ 0.785316930880745,
+ 0.801253812691061,
+ 0.816641555161679,
+ 0.831469612302545,
+ 0.845727821703973,
+ 0.859406411501453,
+ 0.872496007072797,
+ 0.884987637463042,
+ 0.896872741532688,
+ 0.908143173825081,
+ 0.918791210148898,
+ 0.928809552871924,
+ 0.938191335922484,
+ 0.946930129495106,
+ 0.955019944457187,
+ 0.962455236453647,
+ 0.969230909706754,
+ 0.975342320508513,
+ 0.980785280403230,
+ 0.985556059058078,
+ 0.989651386819670,
+ 0.993068456954926,
+ 0.995804927574662,
+ 0.997858923238603,
+ 0.999229036240723,
+ 0.999914327574007,
+ 0.999914327574007,
+ 0.999229036240723,
+ 0.997858923238603,
+ 0.995804927574662,
+ 0.993068456954926,
+ 0.989651386819670,
+ 0.985556059058078,
+ 0.980785280403230,
+ 0.975342320508513,
+ 0.969230909706754,
+ 0.962455236453647,
+ 0.955019944457187,
+ 0.946930129495106,
+ 0.938191335922484,
+ 0.928809552871924,
+ 0.918791210148898,
+ 0.908143173825081,
+ 0.896872741532688,
+ 0.884987637463042,
+ 0.872496007072797,
+ 0.859406411501453,
+ 0.845727821703973,
+ 0.831469612302545,
+ 0.816641555161679,
+ 0.801253812691061,
+ 0.785316930880745,
+ 0.768841832073460,
+ 0.751839807478978,
+ 0.734322509435685,
+ 0.716301943424654,
+ 0.697790459841680,
+ 0.678800745532942,
+ 0.659345815100069,
+ 0.639439001980585,
+ 0.619093949309834,
+ 0.598324600570659,
+ 0.577145190037234,
+ 0.555570233019603,
+ 0.533614515915612,
+ 0.511293086077052,
+ 0.488621241496955,
+ 0.465614520325112,
+ 0.442288690219001,
+ 0.418659737537428,
+ 0.394743856384267,
+ 0.370557437509836,
+ 0.346117057077493,
+ 0.321439465303162,
+ 0.296541574975571,
+ 0.271440449865074,
+ 0.246153293028993,
+ 0.220697435021501,
+ 0.195090322016129,
+ 0.169349503849025,
+ 0.143492621991180,
+ 0.117537397457838,
+ 0.091501618663403,
+ 0.065403129230143,
+ 0.039259815759069,
+ 0.013089595571345
+};
+#endif /* CR9_C_ADD_1p25MS */
+
+#ifdef CR9_C_ADD_1p25MS
+const LC3_INT BW_cutoff_bin_all_1_25ms[] = {10, 20, 30, 40, 50, 50};
+#endif
+
+#ifdef CR9_C_ADD_1p25MS
+const LC3_FLOAT sns_preemph_maxTilt_32[64] = /*Q19 in Word32*/ {
++0.000000000000000e+00, +4.260444641113281e-02, +9.552001953125000e-02, +1.606330871582031e-01, +2.401504516601562e-01, +3.366279602050781e-01, +4.530467987060547e-01, +5.928611755371094e-01, +7.600822448730469e-01, +9.593582153320312e-01, +1.196073532104492e+00, +1.476461410522461e+00, +1.807731628417969e+00, +2.198219299316406e+00, +2.657554626464844e+00, +3.196861267089844e+00, +3.828969955444336e+00, +4.568693161010742e+00, +5.433101654052734e+00, +6.441873550415039e+00, +7.617681503295898e+00, +8.986635208129883e+00, +1.057879638671875e+01, +1.242875480651855e+01, +1.457631111145020e+01, +1.706723594665527e+01, +1.995415306091309e+01, +2.329755401611328e+01, +2.716694641113281e+01, +3.164218902587891e+01, +3.681499481201172e+01, +4.279068374633789e+01, +4.969015884399414e+01, +5.765219688415527e+01, +6.683605003356934e+01, +7.742443466186523e+01, +8.962694740295410e+01, +1.036839809417725e+02, +1.198712043762207e+02, +1.385046882629395e+02, +1.599467639923096e+02, +1.846127471923828e+02, +2.129786052703857e+02, +2.455897598266602e+02, +2.830711212158203e+02, +3.261386032104492e+02, +3.756122741699219e+02, +4.324314041137695e+02, +4.976716747283936e+02, +5.725648708343506e+02, +6.585213947296143e+02, +7.571560096740723e+02, +8.703172912597656e+02, +1.000121299743652e+03, +1.148990077972412e+03, +1.319695686340332e+03, +1.515410537719727e+03, +1.739764961242676e+03, +1.996912996292114e+03, +2.291607635498047e+03, +2.629286834716797e+03, +3.016171834945679e+03, +3.459379568099976e+03, +3.967051151275635e+03
+};
+#else
+const LC3_FLOAT sns_preemph_maxTilt_32[64] = { 1.0000000000, 1.1422936900, 1.3048348743, 1.4905046434, 1.7025940491, 1.9448624389, 2.2216040920, 2.5377243360, 2.8988264960, 3.3113112148, 3.7824899064, 4.3207143526, 4.9355247414, 5.6378187690, 6.4400448053, 7.3564225446, 8.4031950538, 9.5989166860, 10.9647819614, 12.5250012470, 14.3072298919, 16.3430584272, 18.6685725171, 21.3249925879, 24.3594044729, 27.8255940221, 31.7850004725, 36.3078054770, 41.4741770949, 47.3756907943, 54.1169526546, 61.8174535405, 70.6136871125, 80.6615692177, 92.1392015445, 105.2500285278, 120.2264434617, 137.3339077399, 156.8756562372, 179.1980722375, 204.6968271808, 233.8238940558, 267.0955587559, 305.1015713993, 348.5155998248, 398.1071705535, 454.7553088751, 519.4641198313, 593.3805862753, 677.8148994829, 774.2636826811, 884.4365191386, 1010.2862550356, 1154.0436142415, 1318.2567385564, 1505.8363542798, 1720.1073656972, 1964.8677899935, 2244.4560782338, 2563.8280156944, 2928.6445646252, 3345.3722064839, 3821.3975622362, 4365.1583224017 };
+#endif
+
+#ifdef CR9_C_ADD_1p25MS
+const LC3_FLOAT sns_preemph_maxTilt_48[64] = /*Q17 in Word32 */
+{+0.000000000000000e+00, +5.003356933593750e-02, +1.141586303710938e-01, +1.953964233398438e-01, +2.973327636718750e-01, +4.242401123046875e-01, +5.811920166015625e-01, +7.742080688476562e-01, +1.010452270507812e+00, +1.298377990722656e+00, +1.648010253906250e+00, +2.071212768554688e+00, +2.581977844238281e+00, +3.196861267089844e+00, +3.935371398925781e+00, +4.820526123046875e+00, +5.879447937011719e+00, +7.144096374511719e+00, +8.652076721191406e+00, +1.044763946533203e+01, +1.258283996582031e+01, +1.511886596679688e+01, +1.812760925292969e+01, +2.169351959228516e+01, +2.591576385498047e+01, +3.091072845458984e+01, +3.681499481201172e+01, +4.378875732421875e+01, +5.201988220214844e+01, +6.172859954833984e+01, +7.317304229736328e+01, +8.665567016601562e+01, +1.025307922363281e+02, +1.212133789062500e+02, +1.431893615722656e+02, +1.690275802612305e+02, +1.993938980102539e+02, +2.350675277709961e+02, +2.769602203369141e+02, +3.261386032104492e+02, +3.838503112792969e+02, +4.515544738769531e+02, +5.309573440551758e+02, +6.240538558959961e+02, +7.331761932373047e+02, +8.610504531860352e+02, +1.010862823486328e+03, +1.186336814880371e+03, +1.391823417663574e+03, +1.632406326293945e+03, +1.914024772644043e+03, +2.243616851806641e+03, +2.629286834716797e+03, +3.080500373840332e+03, +3.608312332153320e+03, +4.225632614135742e+03, +4.947536384582520e+03, +5.791625976562500e+03, +6.778453254699707e+03, +7.932012306213379e+03, +9.280314323425293e+03, +1.085605828857422e+04, +1.269741340637207e+04, +1.484893192291260e+04
+};
+#else
+const LC3_FLOAT sns_preemph_maxTilt_48[64] = {0.0000000000, 0.0500304087, 0.1141593061, 0.1953976981, 0.2973340176, 0.4242389512, 0.5811887026, 0.7742098746, 1.0104496903, 1.2983759103, 1.6480115389, 2.0712102820, 2.5819797245, 3.1968603815, 3.9353701523, 4.8205253208, 5.8794511276, 7.1440971377, 8.6520751946, 10.4476407528, 12.5828418809, 15.1188643151, 18.1276057212, 21.6935178910, 25.9157621116, 30.9107305378, 36.8149952662, 43.7887571592, 52.0198785456, 61.7285980240, 73.1730420472, 86.6556671708, 102.5307892527, 121.2133820430, 143.1893581115, 169.0275806671, 199.3938963586, 235.0675276210, 276.9602196730, 326.1386032534, 383.8503111474, 451.5544763518, 530.9573444802, 624.0538552089, 733.1761901174, 861.0504505627, 1010.8628231966, 1186.3368169939, 1391.8234195728, 1632.4063284191, 1914.0247716809, 2243.6168519816, 2629.2868351532, 3080.5003754823, 3608.3123335035, 4225.6326173056, 4947.5363821034, 5791.6259768788, 6778.4532561811, 7932.0123088052, 9280.3143269988, 10856.0582896592, 12697.4134068387, 14848.9319246111};
+#endif
+
+const LC3_FLOAT *sns_preemph_adaptMaxTilt_all[6] = {NULL, NULL, NULL, sns_preemph_maxTilt_32, sns_preemph_maxTilt_48, NULL};
+
+#ifdef CR9_C_ADD_1p25MS
+const LC3_INT bands_number_1_25ms[] = {10, 20, 27, 31, 33};
+#endif
+
/* DCT */
#define ENTRY_DCT2_1 {0.353553, 0.000000}
#define ENTRY_DCT2_2 {0.351851, -0.034654}
@@ -540,22 +1265,24 @@ const LC3_FLOAT sns_HFCB[8][32] = {
-1.28790471791471, -1.50335652955529, 0.406319437516838, -3.02457606944550, -0.935353148761338,
-0.656270971328114, 1.75920379670881}};
-const LC3_INT pvq_enc_A[16][11] = {{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
- {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19},
- {0, 1, 5, 13, 25, 41, 61, 85, 113, 145, 181},
- {0, 1, 7, 25, 63, 129, 231, 377, 575, 833, 1159},
- {0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649, 5641},
- {0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073, 22363},
- {0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081, 75517},
- {0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545, 224143},
- {0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729, 598417},
- {0, 1, 19, 181, 1159, 5641, 22363, 75517, 224143, 598417, 1462563},
- {0, 1, 21, 221, 1561, 8361, 36365, 134245, 433905, 1256465, 3317445},
- {0, 1, 23, 265, 2047, 11969, 56695, 227305, 795455, 2485825, 7059735},
- {0, 1, 25, 313, 2625, 16641, 85305, 369305, 1392065, 4673345, 14218905},
- {0, 1, 27, 365, 3303, 22569, 124515, 579125, 2340495, 8405905, 27298155},
- {0, 1, 29, 421, 4089, 29961, 177045, 880685, 3800305, 14546705, 50250765},
- {0, 1, 31, 481, 4991, 39041, 246047, 1303777, 5984767, 24331777, 89129247}};
+const LC3_UINT32 pvq_enc_A[16][11] = {
+ { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 },
+ { 0, 1, 5, 13, 25, 41, 61, 85, 113, 145, 181 },
+ { 0, 1, 7, 25, 63, 129, 231, 377, 575, 833, 1159 },
+ { 0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649, 5641 },
+ { 0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073, 22363 },
+ { 0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081, 75517 },
+ { 0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545, 224143 },
+ { 0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729, 598417 },
+ { 0, 1, 19, 181, 1159, 5641, 22363, 75517, 224143, 598417, 1462563 },
+ { 0, 1, 21, 221, 1561, 8361, 36365, 134245, 433905, 1256465, 3317445 },
+ { 0, 1, 23, 265, 2047, 11969, 56695, 227305, 795455, 2485825, 7059735 },
+ { 0, 1, 25, 313, 2625, 16641, 85305, 369305, 1392065, 4673345, 14218905 },
+ { 0, 1, 27, 365, 3303, 22569, 124515, 579125, 2340495, 8405905, 27298155 },
+ { 0, 1, 29, 421, 4089, 29961, 177045, 880685, 3800305, 14546705, 50250765 },
+ { 0, 1, 31, 481, 4991, 39041, 246047, 1303777, 5984767, 24331777, 89129247 }
+};
const LC3_FLOAT lp_scale_factors[6] = {1, 1, 0.6666666666666666, .5, 0.3333333333333333, 0.16666666666666666};
@@ -4696,6 +5423,7 @@ const LC3_FLOAT MDCT_HRA_WINDOW_480_5ms[480] = {
0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
+
0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00};
@@ -6315,4 +7043,45 @@ const LC3_INT32 mdct_grp_bins[10] = { 4, 14, 24, 44, 84, 164, 244, 324, 404, 484
const LC3_INT16 plc_fadeout_param_maxlen[4] = {800, 400, 266, 200};
const LC3_INT16 plc_fadeout_param_maxbytes[4] = {27, 14, 9, 7};
+#ifdef CR9_C_ADD_1p25MS
+const LC3_FLOAT* MDCT_WINS_1_25ms[2][6] = {
+ {MDCT_WINDOW_80_1_25ms, MDCT_WINDOW_160_1_25ms, MDCT_WINDOW_240_1_25ms, MDCT_WINDOW_320_1_25ms, MDCT_WINDOW_480_1_25ms, NULL},
+ {NULL, NULL, NULL, NULL, NULL, NULL}};
+const LC3_INT MDCT_la_zeroes_1_25ms[6] = {0, 0, 0, 0, 0, 0};
+#endif /* CR9_C_ADD_1p25MS */
+#ifdef CR9_C_ADD_1p25MS
+const LC3_INT MDCT_WINDOWS_LENGTHS_1_25ms[6] = {20, 40, 60, 80, 120, 240};
+#endif
+#ifdef CR9_C_ADD_1p25MS
+const LC3_INT ACC_COEFF_PER_BAND_8_1_25ms[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+const LC3_INT ACC_COEFF_PER_BAND_16_1_25ms[21] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
+
+const LC3_INT ACC_COEFF_PER_BAND_24_1_25ms[28] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, 30};
+
+const LC3_INT ACC_COEFF_PER_BAND_32_1_25ms[32] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 27, 29, 31, 33, 35, 37, 40};
+
+const LC3_INT ACC_COEFF_PER_BAND_48_1_25ms[34] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 46, 50};
+
+const LC3_INT ACC_COEFF_PER_BAND_PLC_8_1_25ms[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+const LC3_INT ACC_COEFF_PER_BAND_PLC_16_1_25ms[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
+
+const LC3_INT ACC_COEFF_PER_BAND_PLC_24_1_25ms[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
+
+const LC3_INT ACC_COEFF_PER_BAND_PLC_32_1_25ms[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40};
+
+const LC3_INT ACC_COEFF_PER_BAND_PLC_48_1_25ms[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60};
+
+const LC3_INT* ACC_COEFF_PER_BAND_PLC_1_25ms[] = {
+ ACC_COEFF_PER_BAND_PLC_8_1_25ms, ACC_COEFF_PER_BAND_PLC_16_1_25ms, ACC_COEFF_PER_BAND_PLC_24_1_25ms, ACC_COEFF_PER_BAND_PLC_32_1_25ms, ACC_COEFF_PER_BAND_PLC_48_1_25ms};
+#endif /* CR9_C_ADD_1p25MS */
+
+#ifdef CR9_C_ADD_1p25MS
+const LC3_INT* ACC_COEFF_PER_BAND_1_25ms[5] = {ACC_COEFF_PER_BAND_8_1_25ms, ACC_COEFF_PER_BAND_16_1_25ms,
+ ACC_COEFF_PER_BAND_24_1_25ms, ACC_COEFF_PER_BAND_32_1_25ms,
+ ACC_COEFF_PER_BAND_48_1_25ms};
+#endif
+
+
const LC3_INT16 PLC_FADEOUT_TYPE_2_SELECTOR = 10; /* can take values from 0 to 10, default is 10 for longer fadeout */
diff --git a/lib_lc3plus/constants.h b/lib_lc3plus/constants.h
index 88d9ed137d7dee795e4393918bc144fad3ebac37..853303e59e161e2d14ea237e6432d7b1fece5d65 100644
--- a/lib_lc3plus/constants.h
+++ b/lib_lc3plus/constants.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -15,6 +15,45 @@
#include "defines.h"
#include "structs.h"
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+extern const LC3_FLOAT lrsns_st1A_topTab_1bitNoDC[2 * 16];
+extern const LC3_INT16 lrsns_ltp_bits[8];
+
+/* BASOP table SNSLR st1B_idx search variables */
+extern const LC3_INT16 st1SCF0_7_base5_32x8_Q11[32 * 8]; /* legacy 10ms quantized BASOP SNS stage1 LF tables 32x8=256 values */
+extern const LC3_INT16 st1SCF8_15_base5_32x8_Q11[32 * 8]; /* legacy 10ms quntized BASOP SNS stage1 HF tables 32x8=256 values */
+
+/* LRSNS st1B, tables to construct from legacy BASOP st1(LF,HF) tables */
+extern const LC3_INT16 lrsns_st1B_merged170orderSortedSegmCnt[4];
+extern const LC3_INT16 lrsns_st1B_merged170orderSortedSegmCum[5];
+extern const LC3_INT16 lrsns_st1B_merged170orderSort12bitIdx[170];
+
+
+/* LRSNS tables to construct st1C from Word8in Q7 and a Q4 scalefactor */
+#ifdef LRSNS_CBC_NO_LTPF_DEPENDENCY
+extern const LC3_FLOAT * lrsns_st1CTrainedMapMeans[2];
+#else
+extern const LC3_FLOAT * lrsns_st1CTrainedMapMeans[3];
+#endif
+extern const LC3_INT8 lrsns_st1C_Both_Word8[170 * 16];
+
+extern const LC3_INT16 lrsns_st1C_Both_scaleQ4_7p4bits_fx[2];
+extern const LC3_INT16 lrsns_st1C_Both_inv_scaleQ15_7p4bits_fx[2];
+
+#endif /* CR9_C_ADD_1p25MS_LRSNS */
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+
+extern const LC3_FLOAT lrsns_gains_Q11[3][8]; /* both enc and dec */
+
+extern const LC3_INT16 signs_fix[SNSLR_N_FIXENV];
+extern const LC3_INT16 env_Qs[SNSLR_N_FIXENV];
+extern const LC3_FLOAT env_Qscale[SNSLR_N_FIXENV];
+extern const LC3_FLOAT shift_en_norm_factors[SNSLR_N_FIXENV][SNSLR_N_FIXENV_SHIFTS];
+extern const LC3_INT32* env_ptrs[SNSLR_N_FIXENV];
+#endif
+
+extern const LC3_FLOAT *sns_preemph_adaptMaxTilt_all[6];
/* DCT */
extern const Complex dct2_16[16];
@@ -30,7 +69,7 @@ extern const LC3_FLOAT sns_W[6];
extern const LC3_FLOAT *sns_preemph_all[6];
extern const LC3_FLOAT sns_LFCB[8][32];
extern const LC3_FLOAT sns_HFCB[8][32];
-extern const LC3_INT pvq_enc_A[16][11];
+extern const LC3_UINT32 pvq_enc_A[16][11];
extern const LC3_FLOAT idct_lookup[M][M];
/* 12.8 kHz resampler */
@@ -113,6 +152,11 @@ extern const LC3_INT bands_number_2_5ms_HR[6];
extern const LC3_INT BW_cutoff_bin_all_2_5ms[MAX_BW_BANDS_NUMBER];
extern const LC3_INT bands_number_2_5ms[5];
+#ifdef CR9_C_ADD_1p25MS
+extern const LC3_INT bands_number_1_25ms[5];
+extern const LC3_INT BW_cutoff_bin_all_1_25ms[];
+#endif
+
extern const LC3_INT BW_warp_idx_start_16k_5ms[4];
extern const LC3_INT BW_warp_idx_stop_16k_5ms[4];
extern const LC3_INT BW_warp_idx_start_24k_5ms[4];
@@ -168,6 +212,19 @@ extern const LC3_FLOAT MDCT_WINDOW_480_5ms[480];
extern const LC3_FLOAT* MDCT_WINS_5ms[2][6];
extern const LC3_INT MDCT_la_zeroes_5ms[6];
+#ifdef CR9_C_ADD_1p25MS
+extern const LC3_FLOAT MDCT_WINDOW_80_1_25ms[20];
+extern const LC3_FLOAT MDCT_WINDOW_160_1_25ms[40];
+extern const LC3_FLOAT MDCT_WINDOW_240_1_25ms[60];
+extern const LC3_FLOAT MDCT_WINDOW_320_1_25ms[80];
+extern const LC3_FLOAT MDCT_WINDOW_480_1_25ms[120];
+extern const LC3_FLOAT* MDCT_WINS_1_25ms[2][6];
+extern const LC3_INT MDCT_la_zeroes_1_25ms[6];
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+extern const LC3_INT16 lrsns_ltp_bits[8];
+#endif
+#endif /* CR9_C_ADD_1p25MS */
+
extern const LC3_FLOAT* MDCT_WINS_7_5ms[2][6];
extern const LC3_INT32 MDCT_la_zeroes_7_5ms[6];
@@ -176,7 +233,16 @@ extern const LC3_INT MDCT_WINDOWS_LENGTHS_7_5ms[6];
extern const LC3_INT MDCT_WINDOWS_LENGTHS_5ms[6];
extern const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6];
+#ifdef CR9_C_ADD_1p25MS
+extern const LC3_INT MDCT_WINDOWS_LENGTHS_1_25ms[6];
+#endif
+
/* Per band energy */
+#ifdef CR9_C_ADD_1p25MS
+extern const LC3_INT* ACC_COEFF_PER_BAND_1_25ms[5];
+extern const LC3_INT* ACC_COEFF_PER_BAND_PLC_1_25ms[5];
+#endif
+
extern const LC3_INT* ACC_COEFF_PER_BAND[6];
extern const LC3_INT* ACC_COEFF_PER_BAND_HR[6];
diff --git a/lib_lc3plus/cutoff_bandwidth.c b/lib_lc3plus/cutoff_bandwidth.c
index a2a617bd0daa57c8ced379a607703d8239de111b..a498dc65e79265b1768ad3f2ccf1ee8f8bc80ad7 100644
--- a/lib_lc3plus/cutoff_bandwidth.c
+++ b/lib_lc3plus/cutoff_bandwidth.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/dct4.c b/lib_lc3plus/dct4.c
index 4b4a3f6a0f344b45c50624eaf7d59ffe1f26c9fa..d90d7f5f5fe6c251017742b0919bfa8dde4570b3 100644
--- a/lib_lc3plus/dct4.c
+++ b/lib_lc3plus/dct4.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -52,8 +52,8 @@ void dct4_init(Dct4* dct, int length)
int i;
assert(length <= MAX_LEN);
dct->length = length;
- dct->twid1 = calloc(sizeof(*dct->twid1), length / 2);
- dct->twid2 = calloc(sizeof(*dct->twid2), length / 2);
+ dct->twid1 = calloc(length / 2, sizeof(*dct->twid1));
+ dct->twid2 = calloc(length / 2, sizeof(*dct->twid2));
for (i = 0; i < length / 2; i++) {
dct->twid1[i] = cexpi(-(LC3_FLOAT)M_PI_LC3PLUS * (i + (LC3_FLOAT)0.25) / length);
dct->twid2[i] = cexpi(-(LC3_FLOAT)M_PI_LC3PLUS * i / length);
diff --git a/lib_lc3plus/dec_entropy.c b/lib_lc3plus/dec_entropy.c
index cd82570a8181fe6df0b838248b5440fd166cdcac..ae39df0169379d4d387275d1a1512218e9b512f1 100644
--- a/lib_lc3plus/dec_entropy.c
+++ b/lib_lc3plus/dec_entropy.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,9 +11,23 @@
#include "wmc_auto.h"
#include "functions.h"
+static const LC3_INT32 gainMSBbits[4] = {1, 1, 2, 2};
+
static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit);
static void read_uint_fl(LC3_INT nbits, LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* val);
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+void readSNSData_fl(LC3_UINT8* ptr, LC3_INT32* bfi, LC3_INT32* mask_side_local, LC3_INT32* bp_side_local, const LC3_INT32* ltpf_idx_2_lrsns, LC3_INT32* sns_vq_idx, LC3PLUS_FrameDuration frame_dms, LC3_INT32 plc_trigger_SNS1, LC3_INT32 plc_trigger_SNS2);
+#else
+void readSNSData_fl(LC3_UINT8* ptr, LC3_INT32* bfi, LC3_INT32* mask_side_local, LC3_INT32* bp_side_local, LC3_INT32* sns_vq_idx, LC3PLUS_FrameDuration frame_dms, LC3_INT32* plc_trigger_SNS1, LC3_INT32* plc_trigger_SNS2);
+#endif
+
+
+
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+void readLtpData_fl(LC3_UINT8* ptr, LC3_INT32* bfiPtr, LC3_INT32* mask_side, LC3_INT32* bp_side, LC3_INT32* ltpf_idx, LC3_INT32* rx_status, LC3_INT32* ltpfinfo_frame_cntr, LC3_INT16* mem_continuation);
+#endif
+
void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit)
{
if (ptr[*bp_side] & *mask_side) {
@@ -54,13 +68,13 @@ LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT
LC3_INT nbbytes = nbbits >> 3;
LC3_INT lastnz;
LC3_INT bw_cutoff_idx;
- LC3_INT nbits = ceil(LC3_LOGTWO(L_spec / 2));
-
+ LC3_INT nbits = getLastNzBits (L_spec);
+
if (nbits > nbbits)
{
return 1;
}
-
+
*np_zero = 0;
*total_padding = 0;
@@ -71,7 +85,7 @@ LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT
if (bp_side < 19 || bp_side >= LC3PLUS_MAX_BYTES) {
return 1;
}
-
+
ptr = bytes;
if (bw_cutoff_bits > 0) {
@@ -90,7 +104,7 @@ LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT
/* Read 4 reserved bits */
read_uint_fl(4, ptr, &mask_side, &bp_side, &val);
-
+
if (ep_enabled == 0)
{
/* Discard padding length bytes */
@@ -102,7 +116,7 @@ LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT
*total_padding = *total_padding + 2;
*np_zero = *np_zero + padding_len;
}
-
+
/* check if minimum payload size is reached */
if ((nbbytes - (*total_padding + *np_zero)) < 20) {
return 1;
@@ -115,26 +129,435 @@ LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT
read_uint_fl(nbits, ptr, &mask_side, &bp_side, &lastnz);
}
-
+
if (ep_enabled != 0)
{
*total_padding = *total_padding + *np_zero;
}
-
+
return 0;
}
#endif
+
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+void readLtpData_fl(
+ LC3_UINT8* ptr,
+ LC3_INT32* bfiPtr,
+ LC3_INT32* mask_side,
+ LC3_INT32* bp_side,
+ LC3_INT32* ltpf_idx,
+ LC3_INT32* rx_status,
+ LC3_INT32* ltpfinfo_frame_cntr,
+ LC3_INT16* mem_continuation
+)
+{
+ LC3_INT32 rx_current_status = -1;
+ LC3_INT32 tmp, MSBs, LSBs;
+
+ /* Hdr, information , bits used
+ 00 , no lag info , no phase info sum=2
+ 010, PhaseA,LTPF=0, lagAbits=4 , sum=7 : PLC may be activated, 4 MSbs
+ 011, PhaseB,LTPF=0, lagBbits=4*, sum=7* : PLC may be activated, 4* = reduced lag resolution in Q_ltpf_Idx domain for PLC-activation
+ 10 , PhaseA,LTPF=1, lagAbits=4 , sum=6 : LTPF activated
+ 11 , PhaseB,LTPF=1, lagBbits=5 , sum=7 : LTPF activated
+ */
+
+ ltpf_idx[2] = -1; /* no ready lag available, conditionally decoded if phase is B, and consecutive A/B has arrived */
+
+ read_uint_fl(2, ptr, mask_side, bp_side, &tmp);
+ if (tmp == 0) /* "00" */
+ {
+ ltpf_idx[0] = 0; /* ltp ltpf/lag was not transmitted */
+ ltpf_idx[1] = 0; /* ltpf activation bit zeroed */
+
+ rx_status[0] = -32768; /* set unknown phase A , due to rx LTP==0 */
+ rx_status[1] = -1; /* set unknown phase A MSBs content */
+ *ltpfinfo_frame_cntr = -32768;
+ assert(ltpf_idx[2] < 0); /* ltpf_idx[2] = -1; , no ready lag available */
+#ifdef FIX_LTPF_1p25
+ *mem_continuation = 0; /* also kill lag continuation state */
+#endif
+ }
+ else if (tmp == 1) /* "01" */
+ {
+ ltpf_idx[0] = 1;
+ ltpf_idx[1] = 0; /* LTP=1, LTPF=0, inactive ltpf */
+ read_bit_fl(ptr, mask_side, bp_side, &rx_current_status);
+
+ if (rx_current_status == 0)
+ {
+ rx_status[0] = 0; /* phaseA */
+ read_uint_fl(4, ptr, mask_side, bp_side, &(rx_status[1])); /* read four MSBs, and store in rx_status[1] */
+#ifdef FIX_LTPF_1p25
+ if (*mem_continuation == 0)
+ {
+ *mem_continuation = 1;
+ }
+#endif
+ *ltpfinfo_frame_cntr = 0; /*same as rx_status [0] */
+ }
+ else
+ { /* LSB part of delta coded lag information */
+ assert(rx_current_status == 1);
+ read_uint_fl(4, ptr, mask_side, bp_side, &LSBs);
+ LSBs = (LSBs << 1); /* NB Least Signifcant bit is on purpose always zero, truncation on encoder side */
+ if ( rx_status[1] < 0 )
+ {
+ *bfiPtr = 1;
+ return;
+ }
+ ltpf_idx[2] = ((rx_status[1] << 5) | LSBs); /* bitwise OR */
+
+ /* check frame cntr info to not combine oldA with a newB */
+ if (*ltpfinfo_frame_cntr != 1)
+ {
+ rx_status[0] = -32768; /*even number of bfi frames may have happened */
+ ltpf_idx[1] = 0;
+ ltpf_idx[2] = -1; /* send signal of non-decoded lag to PLC and LTPF decoder */
+ }
+#ifdef FIX_LTPF_MEM_CONTINUATION
+ else
+ {
+ *mem_continuation = 0;
+ }
+ # endif
+ rx_status[0] = -32768;
+ *ltpfinfo_frame_cntr = -32678;
+ }
+ }
+ else
+ { /* 2 or 3 */
+ ltpf_idx[0] = 1;
+ ltpf_idx[1] = 1; /* active ltpf */
+
+ if (tmp == 2) /* 2="10" */
+ {
+ /* phaseA */
+ read_uint_fl(4, ptr, mask_side, bp_side, &MSBs);
+
+ rx_status[0] = 0;
+ rx_status[1] = MSBs; /* remember the four MSBs */
+#ifdef FIX_LTPF_1p25
+ if (*mem_continuation == 0)
+ {
+ *mem_continuation = 1;
+ }
+#endif
+ *ltpfinfo_frame_cntr = 0;
+ assert(ltpf_idx[2] < 0); /* ltpf_idx[2] = -1; , no ready lag available */
+ }
+ else
+ { /* 3="11" */
+ assert(tmp == 3); /* phaseB */
+ read_uint_fl(5, ptr, mask_side, bp_side, &LSBs); /* all 5 LSBs available*/
+ if ( rx_status[1] < 0 )
+ {
+ *bfiPtr = 1;
+ return;
+ }
+ ltpf_idx[2] = ((rx_status[1] << 5) | LSBs); /* bitwise OR */
+
+ /* check frame cntr info to not combine oldA with a newB */
+ if (*ltpfinfo_frame_cntr != 1)
+ {
+ ltpf_idx[1] = 0; /* turn off LTPF activation for now, so that ltpf_idx[2] is not read */
+ ltpf_idx[2] = -1; /* send signal to PLC and ltpf_decoder, that phase B could not be decoded */
+ }
+ *ltpfinfo_frame_cntr = -32678; /*cntr init in phaseA*/
+ rx_status[0] = -32768; /* phase init in phaseA*/
+
+#ifdef FIX_LTPF_MEM_CONTINUATION
+ *mem_continuation = 0;
+#endif
+ }
+ }
+
+}
+#endif
+
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+void readSNSData_fl(LC3_UINT8* ptr, LC3_INT32* bfi, LC3_INT32* mask_side_local, LC3_INT32* bp_side_local, const LC3_INT32* ltpf_idx_2_lrsns,
+ LC3_INT32* sns_vq_idx, LC3PLUS_FrameDuration frame_dms,
+ LC3_INT32 plc_trigger_SNS1, LC3_INT32 plc_trigger_SNS2)
+#else
+void readSNSData_fl(LC3_UINT8* ptr, LC3_INT32* bfi, LC3_INT32* mask_side_local, LC3_INT32* bp_side_local, LC3_INT32* sns_vq_idx,
+ LC3PLUS_FrameDuration frame_dms, LC3_INT32* plc_trigger_SNS1, LC3_INT32* plc_trigger_SNS2)
+#endif
+{
+ LC3_INT32 tmp, submodeMSB, idxBorGainLSB, submodeLSB;
+#ifndef CR9_C_ADD_1p25MS
+ (void) frame_dms;
+#endif
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ LC3_INT32 read_legacy_sns_vq_bits;
+#endif
+
+
+ UNUSED(frame_dms);
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ read_legacy_sns_vq_bits = 1;
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ read_legacy_sns_vq_bits = 0; /* decode 9, 10, or 29/30 bits */
+ }
+
+ if (read_legacy_sns_vq_bits != 0)
+ {
+#endif
+ /* SNS-VQ 1st stage */
+ read_uint_fl(5, ptr, mask_side_local, bp_side_local, &sns_vq_idx[SNS_IDX_LF]);
+ read_uint_fl(5, ptr, mask_side_local, bp_side_local, &sns_vq_idx[SNS_IDX_HF]);
+
+ /* SNS-VQ 2nd stage side-info (3-4 bits) */
+ read_bit_fl(ptr, mask_side_local, bp_side_local, &submodeMSB);
+
+ read_uint_fl(gainMSBbits[submodeMSB * 2], ptr, mask_side_local, bp_side_local, &sns_vq_idx[SNS_IDX_GAIN]);
+ read_bit_fl(ptr, mask_side_local, bp_side_local, &sns_vq_idx[SNS_IDX_LS_INDA]);
+
+ /* SNS-VQ 2nd stage VQ decoding (24-25 bits) */
+ if (submodeMSB == 0)
+ {
+ read_uint_fl(25, ptr, mask_side_local, bp_side_local, &tmp);
+ if (tmp >= 33460056)
+ {
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ *bfi = plc_trigger_SNS1;
+#else
+ *bfi = *plc_trigger_SNS1;
+#endif
+ if (*bfi)
+ {
+ return;
+ }
+ }
+ idxBorGainLSB = floor(tmp / 2390004);
+ sns_vq_idx[SNS_IDX_A] = tmp - idxBorGainLSB * 2390004;
+
+ if (idxBorGainLSB < 2)
+ {
+ submodeLSB = 1;
+ sns_vq_idx[SNS_IDX_GAIN] = sns_vq_idx[SNS_IDX_GAIN] * 2 + idxBorGainLSB;
+ sns_vq_idx[SNS_IDX_BORGAINLSB] = -2;
+ }
+ else
+ {
+ submodeLSB = 0;
+ sns_vq_idx[SNS_IDX_BORGAINLSB] = idxBorGainLSB - 2;
+ }
+ }
+ else
+ {
+ read_uint_fl(24, ptr, mask_side_local, bp_side_local, &tmp);
+ if (tmp >= 16708096)
+ {
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ *bfi = plc_trigger_SNS2;
+#else
+ *bfi = *plc_trigger_SNS2;
+#endif
+ if (*bfi)
+ {
+ return;
+ }
+ }
+
+ if (tmp >= 15158272)
+ {
+ submodeLSB = 1;
+ tmp -= 15158272;
+ sns_vq_idx[SNS_IDX_GAIN] = sns_vq_idx[SNS_IDX_GAIN] * 2 + (tmp & 1);
+ sns_vq_idx[SNS_IDX_A] = floor(tmp / 2);
+ sns_vq_idx[SNS_IDX_BORGAINLSB] = -2;
+ }
+ else
+ {
+ submodeLSB = 0;
+ sns_vq_idx[SNS_IDX_A] = tmp;
+ sns_vq_idx[SNS_IDX_BORGAINLSB] = -1;
+ }
+ }
+
+ sns_vq_idx[SNS_IDX_SHAPEJ] = submodeMSB * 2 + submodeLSB;
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ }
+
+ if (read_legacy_sns_vq_bits == 0)
+ {
+ LC3_INT32 shape_idx = -1;
+ LC3_INT32 gain_idx = -1;
+ LC3_INT32 aux_idx = -1;
+ LC3_INT32 tmp_shape = -1;
+ LC3_INT32 stop_bit = -1;
+ /* SNS-VQ 1st stage in 9-10 bits */
+ read_uint_fl(9, ptr, mask_side_local, bp_side_local, &sns_vq_idx[SNS_IDX_LF]);
+ if (sns_vq_idx[SNS_IDX_LF] >= 510) /* stage 1A */
+ {
+ assert(sns_vq_idx[SNS_IDX_LF] < 512);
+ sns_vq_idx[SNS_IDX_LF] -= 510; /* send only idx 0,1 */
+ sns_vq_idx[SNS_IDX_HF] = -32768; /* unused */
+ shape_idx = -9;
+ sns_vq_idx[2] = shape_idx; /* actual signal to LR SNS vector reconstruction */
+ }
+ else
+ {
+ /* read stop bit */
+ read_uint_fl(1, ptr, mask_side_local, bp_side_local, &stop_bit);
+ sns_vq_idx[SNS_IDX_HF] = -32768; /* unused */
+
+ if (sns_vq_idx[SNS_IDX_LF] < (2 * 170) && stop_bit != 0)
+ {
+ /*B or C , keep values 0...339 in sns_vq_idx[0] , so that stage1 B vs stage1 C can be determined later in the DecLR function */
+ sns_vq_idx[2] = -10;
+ sns_vq_idx[3] = ltpf_idx_2_lrsns[0]; /* forward LTP active flag */
+ sns_vq_idx[4] = ltpf_idx_2_lrsns[1]; /* forward LTPF active flag */
+ }
+ else
+ { /* stage1B + stage2 */
+ /*0...169 in sns_vq_idx[0]*/
+ if (sns_vq_idx[SNS_IDX_LF] < (2 * 170) && stop_bit == 0)
+ {
+ aux_idx = 0;
+ if (sns_vq_idx[SNS_IDX_LF] >= (170))
+ {
+ aux_idx = 1;
+ sns_vq_idx[SNS_IDX_LF] -= 170;
+ }
+ sns_vq_idx[SNS_IDX_HF] = aux_idx; /* aux bit for , LR_Split_LF, 29 bits */
+
+ shape_idx = 0; /* point to splitLF parsing */
+ sns_vq_idx[2] = shape_idx;
+
+ read_uint_fl(2, ptr, mask_side_local, bp_side_local, &gain_idx);
+ sns_vq_idx[3] = gain_idx;
+
+ /* stage2 shape demux for LR_splitLF */
+ read_uint_fl(10, ptr, mask_side_local, bp_side_local, &sns_vq_idx[4]); /* 10bits mPVQ(N=5,K=6) */
+
+ if (sns_vq_idx[4] >= (SNSLR_NPVQ_L5K6 >> 1) + (1 << 5)) /* some limited bit error detection possible here */
+ {
+ *bfi = plc_trigger_SNS1;
+ if (*bfi != 0)
+ {
+ return;
+ }
+ }
+
+ /* determine section of splitLF mpvq(5,6)+P(8,2)+P(2,0) or mpvq(5,8)+P(10,0) */
+ if (sns_vq_idx[4] < (SNSLR_NPVQ_L5K6 >> 1))
+ {
+ read_uint_fl(1, ptr, mask_side_local, bp_side_local, &tmp_shape); /* LS (8,2) */
+ read_uint_fl(6, ptr, mask_side_local, bp_side_local, &sns_vq_idx[5]); /* mPVQ(8,2) */
+ sns_vq_idx[5] = (sns_vq_idx[5] << 1) + tmp_shape; /* P(8,2) LS put as lsb */
+ }
+ else
+ {
+ sns_vq_idx[4] = sns_vq_idx[4] - (SNSLR_NPVQ_L5K6 >> 1); /* 5 LSBs of mpvq (5,8) */
+
+ read_uint_fl(7, ptr, mask_side_local, bp_side_local, &sns_vq_idx[5]); /* 7 msbs of mPVQ(5,8) */
+ sns_vq_idx[4] = (sns_vq_idx[5] << 5) | sns_vq_idx[4]; /* merge MSB's and LSBs */
+ sns_vq_idx[5] = -8; /* signal to sns_decoder split_LF subshape to decode 8 lf pulses, and no hf pulses */
+
+ if (sns_vq_idx[4] >= (SNSLR_NPVQ_L5K8 >> 1)) {
+ *bfi = plc_trigger_SNS1;
+ if (*bfi != 0) {
+ return;
+ }
+ }
+ }
+ }
+ else if (sns_vq_idx[SNS_IDX_LF] >= (2 * 170))
+ {
+ aux_idx = stop_bit;
+ sns_vq_idx[SNS_IDX_LF] -= (2 * 170);
+ sns_vq_idx[1] = aux_idx;
+
+ shape_idx = 1; /* point to full parsing */
+ sns_vq_idx[2] = shape_idx; /* LR_full , 30 bits */
+
+ read_uint_fl(3, ptr, mask_side_local, bp_side_local, &gain_idx);
+ sns_vq_idx[3] = gain_idx;
+
+ /* stage2 shape demux for LR_full */
+ read_uint_fl(17, ptr, mask_side_local, bp_side_local, &sns_vq_idx[4]); /* 16.666 bits mPVQ(N=15,K=5) */
+
+ if (sns_vq_idx[4] >= (SNSLR_NPVQ_L15K5 >> 1))
+ { /* fixenv shapes demultiplexing */
+ sns_vq_idx[5] = (sns_vq_idx[4] - (SNSLR_NPVQ_L15K5 >> 1));
+ if (sns_vq_idx[5] < (3 * (1 << 13)))
+ { /*fix_env's "0,1,2" with 2 shiftbits and 11 remaining sign bits s1..s11 */
+ sns_vq_idx[4] = 0;
+ while (sns_vq_idx[5] >= (1 << 13)) {
+ sns_vq_idx[5] = sns_vq_idx[5] - (1 << 13);
+ sns_vq_idx[4] += 1;
+ }
+ assert(sns_vq_idx[4] >= 0 && sns_vq_idx[4] <= 3);
+ assert(sns_vq_idx[5] >= 0 && sns_vq_idx[5] < (1 << 13));
+ }
+ else if (sns_vq_idx[5] < (3 * (1 << 13) + (1 << 11)))
+ {
+ sns_vq_idx[4] = 3; /*smaller fix_env "3" with 2 shiftbits and 9 remaining sign bits s1..s9 */
+ sns_vq_idx[5] = sns_vq_idx[5] - (3 * (1 << 13));
+ assert(sns_vq_idx[5] >= 0 && sns_vq_idx[5] < (1 << 11));
+ }
+ else
+ { /* bit error */
+ *bfi = plc_trigger_SNS2;
+ if (*bfi != 0)
+ {
+ return;
+ }
+ }
+ shape_idx = sns_vq_idx[4] + 2;
+ sns_vq_idx[2] = shape_idx;
+ } /* fixenv */
+ }/*full*/
+ }/*stage1B* + stage2 */
+ } /*10+ bits*/
+ }
+#endif
+#ifdef LRSNS_PC_SIGNAL_FIX
+ assert(*bfi == 0 || *bfi == 1 ); /* local SNS BFI-flag output check */
+#endif
+}
+
void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT N, LC3_INT fs_idx,
- LC3_INT bw_cutoff_bits, LC3_INT* bfi, LC3_INT* gg_idx, LC3_INT* scf_idx, LC3_INT* fac_ns_idx,
+ LC3_INT bw_cutoff_bits, LC3_INT* bfi, LC3_INT* gg_idx, LC3_INT* sns_vq_idx, LC3_INT* fac_ns_idx,
LC3_INT* tns_numfilters, LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* bw_cutoff_idx, LC3_INT* lastnz,
- LC3_INT* lsbMode, LC3_INT frame_dms)
+ LC3_INT* lsbMode, LC3PLUS_FrameDuration frame_dms
+#ifdef CR9_C_ADD_1p25MS
+ , LC3_INT32 rx_status[2], LC3_INT16* mem_continuation
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ , LC3_INT32 *ltpfinfo_frame_cntr /* set here , but also increased outside by bfi for the channel */
+#endif
+#endif
+ )
{
- LC3_INT plc_trigger_bw, plc_trigger_last_nz, plc_trigger_SNS1, plc_trigger_SNS2, tmp, bit,
- submodeMSB, i, ltpf_tmp[3], ind, submodeLSB, bp_side_local, mask_side_local;
- LC3_UINT8* ptr;
- LC3_INT gainMSBbits[4] = {1, 1, 2, 2};
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ LC3_INT32 plc_trigger_bw, plc_trigger_last_nz, plc_trigger_SNS1, plc_trigger_SNS2, bit,
+ i, ltpf_tmp[3], bp_side_local, mask_side_local, rx_current_status, ltpf_idx_2_lrsns[3];
+ LC3_UINT8 * ptr;
+#ifdef LRSNS_PC_SIGNAL_FIX
+ LC3_INT bfiSNS;
+#endif
+
+ //UNUSED(rx_status);
+ //UNUSED(mem_continuation);
+ UNUSED(rx_current_status);
+#else
+ LC3_INT32 plc_trigger_bw, plc_trigger_last_nz, plc_trigger_SNS1, plc_trigger_SNS2, bit,
+ i, ltpf_tmp[3], bp_side_local, mask_side_local, rx_current_status;
+ LC3_UINT8 * ptr;
+ UNUSED(rx_current_status);
+#endif
+
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ UNUSED(rx_current_status);
+#endif
*bp_side = -1;
bp_side_local = numbytes - 1; /* Matlab offset by 1 */
@@ -146,11 +569,13 @@ void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_
plc_trigger_bw = 1; /* Bandwidth */
plc_trigger_last_nz = 1; /* Last non-zero tuple */
- plc_trigger_SNS1 = 1; /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */
- plc_trigger_SNS2 = 1; /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */
-
-
+ plc_trigger_SNS1 = 1; /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */
+#ifdef LRSNS_10MS_BFISIGNAL_FIX
+ plc_trigger_SNS2 = 1; /* SNS-VQ 2nd stage MPVQ data (10-16 bits) */
+#else
+ plc_trigger_SNS2 = 2; /* SNS-VQ 2nd stage MPVQ data (10-16 bits) */
+#endif
/* Bandwidth */
if (bw_cutoff_bits > 0) {
read_uint_fl(bw_cutoff_bits, ptr, &mask_side_local, &bp_side_local, bw_cutoff_idx);
@@ -167,14 +592,22 @@ void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_
}
/* Number of TNS filters */
- if (*bw_cutoff_idx < 3 || frame_dms == 25) {
- *tns_numfilters = 1;
+#ifdef CR9_C_ADD_1p25MS
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ *tns_numfilters = 0;
} else {
- *tns_numfilters = 2;
+#endif
+ if (*bw_cutoff_idx < 3 || frame_dms == LC3PLUS_FRAME_DURATION_2p5MS) {
+ *tns_numfilters = 1;
+ } else {
+ *tns_numfilters = 2;
+ }
+#ifdef CR9_C_ADD_1p25MS
}
+#endif
/* Last non-zero tuple */
- read_uint_fl(ceil(LC3_LOGTWO(N >> 1)), ptr, &mask_side_local, &bp_side_local, lastnz);
+ read_uint_fl(getLastNzBits (N), ptr, &mask_side_local, &bp_side_local, lastnz);
*lastnz = (*lastnz + 1) * 2;
if (*lastnz > N) {
@@ -197,73 +630,85 @@ void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_
}
/* LTPF activation flag */
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ ltpf_tmp[1] = 0; /* ltpf activation idx */
+ ltpf_tmp[2] = 0; /* quantized lag idx */
+ if (frame_dms != LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ read_bit_fl(ptr, &mask_side_local, &bp_side_local, <pf_tmp[0]);
+ }
+ else
+ { /* read one of {2, 6, 7} bits into ltp/ltpf/lag variable ltpf_idx[ 0 ... 2] */
+ readLtpData_fl(ptr, bfi, &mask_side_local, &bp_side_local, ltpf_tmp, rx_status, ltpfinfo_frame_cntr, mem_continuation);
+ } /* ! LC3PLUS_FRAME_DURATION_1p25MS */
+#else
read_bit_fl(ptr, &mask_side_local, &bp_side_local, <pf_tmp[0]);
+#endif
- /* SNS-VQ 1st stage */
- read_uint_fl(5, ptr, &mask_side_local, &bp_side_local, &scf_idx[0]);
- read_uint_fl(5, ptr, &mask_side_local, &bp_side_local, &scf_idx[1]);
-
- /* SNS-VQ 2nd stage side-info (3-4 bits) */
- read_bit_fl(ptr, &mask_side_local, &bp_side_local, &submodeMSB);
- scf_idx[2] = submodeMSB * 2;
-
- read_uint_fl(gainMSBbits[scf_idx[2]], ptr, &mask_side_local, &bp_side_local, &scf_idx[3]);
- read_bit_fl(ptr, &mask_side_local, &bp_side_local, &scf_idx[4]);
-
- /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */
- if (submodeMSB == 0) {
- read_uint_fl(25, ptr, &mask_side_local, &bp_side_local, &tmp);
- if (tmp >= 33460056) {
- *bfi = plc_trigger_SNS1;
- if (*bfi) {
- return;
- }
- }
-
- ind = floor(tmp / 2390004);
- scf_idx[5] = tmp - ind * 2390004;
+ /* read SNS data */
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ ltpf_idx_2_lrsns[0] = ltpf_tmp[0]; /* raw LTP flag input to LRSNS */
+ ltpf_idx_2_lrsns[1] = ltpf_tmp[1]; /* raw LTPF flag input to LRSNS */
+#ifdef LRSNS_PC_SIGNAL_FIX
+ bfiSNS = 0; /* Local BFI flag for Errors SNS bit area */
+ readSNSData_fl(ptr, &bfiSNS, &mask_side_local, &bp_side_local, ltpf_idx_2_lrsns, sns_vq_idx, frame_dms, plc_trigger_SNS1, plc_trigger_SNS2);
+ if (bfiSNS != 0 )
+ { /* corrupt SNSbits triggers PLC through global PLC flag.
+ *bfi==2 and bfiSNS == 0 maintains bfi==2 for PC
+ */
+ *bfi = 1;
+ return;
+ }
- if (ind < 2) {
- submodeLSB = 1;
- scf_idx[3] = scf_idx[3] * 2 + ind;
- scf_idx[6] = -2;
- } else {
- submodeLSB = 0;
- scf_idx[6] = ind - 2;
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ { /* for 1.25ms and previously detected bit errors --> handle frame as a completely corrupt bad frame */
+ if (*bfi == 2)
+ {
+ *bfi = 1;
+ return;
}
+ }
- } else {
- read_uint_fl(24, ptr, &mask_side_local, &bp_side_local, &tmp);
-
- if (tmp >= 16708096) {
- *bfi = plc_trigger_SNS2;
- if (*bfi) {
- return;
- }
- }
+#else
+ readSNSData_fl(ptr, bfi, &mask_side_local, &bp_side_local, ltpf_idx_2_lrsns, sns_vq_idx, frame_dms, plc_trigger_SNS1, plc_trigger_SNS2);
+ if (*bfi != 0)
+ {
+ *bfi = 1;
+ return;
+ }
+#endif
+#else
+ readSNSData_fl(ptr, bfi, &mask_side_local, &bp_side_local, sns_vq_idx, frame_dms, &plc_trigger_SNS1, &plc_trigger_SNS2);
+#endif
- if (tmp >= 15158272) {
- submodeLSB = 1;
- scf_idx[3] = scf_idx[3] * 2 + ((tmp - 15158272) & 1);
- scf_idx[5] = floor((tmp - 15158272) / 2);
- scf_idx[6] = -2;
- } else {
- submodeLSB = 0;
- scf_idx[5] = tmp;
- scf_idx[6] = -1;
+ /* LTPF data */
+#ifdef CR9_C_ADD_1p25MS
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ if ( frame_dms != LC3PLUS_FRAME_DURATION_1p25MS )
+ {
+ ltpf_tmp[1] = 0;
+ ltpf_tmp[2] = 0;
+ if (ltpf_tmp[0] == 1)
+ {
+ read_bit_fl(ptr, &mask_side_local, &bp_side_local, <pf_tmp[1]);
+ read_uint_fl(9, ptr, &mask_side_local, &bp_side_local, <pf_tmp[2]);
}
}
+#endif
+#endif
- scf_idx[2] = scf_idx[2] + submodeLSB;
-
- /* LTPF data */
- if (ltpf_tmp[0] == 1) {
+#ifndef CR9_C_ADD_1p25MS
+ if (ltpf_tmp[0] == 1)
+ {
read_bit_fl(ptr, &mask_side_local, &bp_side_local, <pf_tmp[1]);
read_uint_fl(9, ptr, &mask_side_local, &bp_side_local, <pf_tmp[2]);
- } else {
+ }
+ else
+ {
ltpf_tmp[1] = 0;
ltpf_tmp[2] = 0;
}
+#endif /* CR9_C_ADD_1p25MS */
for (i = 0; i < 3; i++) {
ltpf_idx[i] = ltpf_tmp[i];
@@ -271,7 +716,7 @@ void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_
/* Noise factor */
read_uint_fl(3, ptr, &mask_side_local, &bp_side_local, fac_ns_idx);
-
+
*bp_side = bp_side_local;
*mask_side = mask_side_local;
}
diff --git a/lib_lc3plus/dec_lc3_fl.c b/lib_lc3plus/dec_lc3_fl.c
index f86eff3430dd64fd952c316e0e27aca0da0a8d62..3606077cefd22062f04d5cb5e5c904ec30807cc0 100644
--- a/lib_lc3plus/dec_lc3_fl.c
+++ b/lib_lc3plus/dec_lc3_fl.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -19,9 +19,13 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs
i = 0, tns_order[2] = {0}, sqQdec[MAX_LEN] = {0};
LC3_INT b_left;
LC3_FLOAT stab_fac = 0;
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ LC3_INT32 pitch_rx;
+ LC3_INT32 ltpf_rx;
+#endif
h_DecSetup = decoder->channel_setup[channel];
-
+
memset(h_DecSetup->tns_idx, 0, sizeof(*h_DecSetup->tns_idx) * TNS_NUMFILTERS_MAX * MAXLAG);
bfi = bfi_ext;
@@ -33,15 +37,31 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs
decoder->rframe = 1;
}
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ h_DecSetup->ltpfinfo_frame_cntr = MIN(32767, h_DecSetup->ltpfinfo_frame_cntr + 1); /*increased always, also for bfi==1 */ /* set or reset inside processDecoderEntropy_fl */
+#endif
+
/* Entropy decoding */
if (bfi != 1) {
processDecoderEntropy_fl(bs_in, h_DecSetup->targetBytes, &mask_side, &bp_side, decoder->yLen, decoder->fs_idx,
decoder->BW_cutoff_bits, &bfi, &gg_idx, h_DecSetup->scf_idx, &fac_ns_idx,
&tns_numfilters, tns_order, h_DecSetup->ltpf_param, &bw_cutoff_idx, &lastnz, &lsbMode, decoder->frame_dms
+
+
+#ifdef CR9_C_ADD_1p25MS
+#ifdef FIX_TX_RX_STRUCT_STEREO
+ , h_DecSetup->ltpf_rx_status, &h_DecSetup->ltpf_mem_continuation
+#else
+ , decoder->ltpf_rx_status, &h_DecSetup->ltpf_mem_continuation
+#endif
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ , &h_DecSetup->ltpfinfo_frame_cntr /* set here, but also increased outside during/when bfi for the channel */
+#endif
+#endif
);
h_DecSetup->BW_cutoff_idx_nf = bw_cutoff_idx;
}
-
+
/* Arithmetic decoding */
if (bfi != 1) {
processAriDecoder_fl(bs_in, bp_side, mask_side, decoder->yLen, decoder->fs_idx,
@@ -50,26 +70,33 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs
decoder->n_pc, decoder->be_bp_left, decoder->be_bp_right, 0, &b_left, &h_DecSetup->spec_inv_idx,
decoder->hrmode
);
-
+
if (decoder->rframe == 1 && zero_frame == 0 && bfi != 1)
{
LC3_INT32 max_bw_stopband = BW_cutoff_bin_all[bw_cutoff_idx];
bfi = 2;
switch (decoder->frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ max_bw_stopband = max_bw_stopband >> 3;
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
max_bw_stopband = max_bw_stopband >> 2;
break;
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
max_bw_stopband = max_bw_stopband >> 1;
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
max_bw_stopband = 3 * (max_bw_stopband >> 2);
break;
- case 100:
+ case LC3PLUS_FRAME_DURATION_10MS:
break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
-
+
h_DecSetup->spec_inv_idx = MAX(lastnz, max_bw_stopband);
}
@@ -78,18 +105,33 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs
h_DecSetup->sqQdec_fl[i] = (LC3_FLOAT)sqQdec[i];
}
}
-
+
if (bfi != 1)
{
/* SNS Quantize Decoder */
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ if (decoder->frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) /* 9,10,29,30 bit low rate SNS VQ */
+ {
+ pitch_rx = ( h_DecSetup->ltpf_param[0] != 0 );
+ ltpf_rx = ( h_DecSetup->ltpf_param[1] != 0 ) ;
+
+ snsQuantScfDecLR(h_DecSetup->scf_idx, h_DecSetup->scf_q, pitch_rx, ltpf_rx); /* 9,12,29,30, bits decoding including pitch_rx, ltpf_rx info */
+ }
+ else
+ {
+ process_snsQuantizesScf_Dec(h_DecSetup->scf_idx, h_DecSetup->scf_q); /* 38 bits decoded */
+ }
+#else
+ /* SNS Quantize Decoder */
process_snsQuantizesScf_Dec(h_DecSetup->scf_idx, h_DecSetup->scf_q);
+#endif
}
if (h_DecSetup->PlcAdvSetup)
{
processPlcComputeStabFacMain_fl(h_DecSetup->scf_q, h_DecSetup->PlcAdvSetup->scf_q_old, h_DecSetup->PlcAdvSetup->scf_q_old_old, bfi, h_DecSetup->PlcSetup.prevBfi,
h_DecSetup->PlcSetup.prevprevBfi, &h_DecSetup->PlcAdvSetup->stabFac);
}
-
+
if ( bfi != 1 )
{
stab_fac = 1;
@@ -103,28 +145,52 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs
fac_ns_idx, &h_DecSetup->statePC, h_DecSetup->spec_inv_idx, decoder->yLen);
}
+#ifdef CR9_C_ADD_1p25MS
+ if ( bfi == 1 )
+ {
+#ifdef FIX_TX_RX_STRUCT_STEREO
+ h_DecSetup->ltpf_rx_status[0] = 0;
+ h_DecSetup->ltpf_rx_status[1] = 0;
+#else
+ decoder->ltpf_rx_status[0] = 0;
+ decoder->ltpf_rx_status[1] = 0;
+#endif
+ }
+#endif
+
/* Decoding only if no bit error detected */
if (bfi != 1) {
/* Residual decoding */
if (residualPresent) {
- processResidualDecoding_fl(&bitsRead, h_DecSetup->sqQdec_fl, decoder->yLen, h_DecSetup->resBits,
- nbits_residual
- , decoder->hrmode
+ processResidualDecoding_fl(&bitsRead, h_DecSetup->sqQdec_fl, decoder->yLen, h_DecSetup->resBits, nbits_residual, decoder->hrmode
+#ifdef ENABLE_12p5_DMS_MODE
+ , decoder->frame_dms
+#endif
);
}
-
-
+
/* Noise filling */
- if (zero_frame == 0) {
+#ifdef CR9_C_ADD_1p25MS
+ if (zero_frame == 0 && decoder->cutoffBins != NULL)
+#else
+ if (zero_frame == 0)
+#endif
+ {
processNoiseFilling_fl(h_DecSetup->sqQdec_fl, nf_seed, fac_ns_idx, decoder->cutoffBins[h_DecSetup->BW_cutoff_idx_nf], decoder->frame_dms, h_DecSetup->prev_fac_ns, h_DecSetup->spec_inv_idx);
}
-
+
/* Application of global gain */
processApplyGlobalGain_fl(h_DecSetup->sqQdec_fl, decoder->yLen, gg_idx, h_DecSetup->quantizedGainOff);
/* TNS decoder */
+#ifdef CR9_C_ADD_1p25MS
+ if (tns_numfilters > 0) {
+#endif
processTnsDecoder_fl(h_DecSetup->sqQdec_fl, h_DecSetup->tns_idx, tns_order, tns_numfilters,
decoder->cutoffBins[bw_cutoff_idx], h_DecSetup->N_red_tns, h_DecSetup->fs_red_tns);
+#ifdef CR9_C_ADD_1p25MS
+ }
+#endif
/* SNS interpolation */
processSnsInterpolateScf_fl(h_DecSetup->scf_q, 0, decoder->bands_number, h_DecSetup->int_scf);
@@ -132,7 +198,7 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs
/* MDCT shaping */
processMdctShaping_fl(h_DecSetup->sqQdec_fl, h_DecSetup->int_scf, decoder->bands_offset, decoder->bands_number);
}
-
+
/* PLC */
processPlcMain_fl(h_DecSetup->sqQdec_fl, h_DecSetup->x_fl, decoder, h_DecSetup, bfi, h_DecSetup->PlcAdvSetup, &h_DecSetup->PlcSetup,
decoder->plcMeth, h_DecSetup->ltpf_mem_pitch, h_DecSetup->ltpf_mem_pitch_fr, decoder->tilt, decoder->bands_offset,
@@ -147,7 +213,7 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs
&h_DecSetup->PlcAdvSetup->cum_fflcAtten
, h_DecSetup->PlcAdvSetup->plc_fadeout_type
);
-
+
/* IMDCT */
if (h_DecSetup->concealMethod == 4 || bfi != 1 )
{
@@ -158,15 +224,20 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs
processPlcUpdate_fl(h_DecSetup->PlcAdvSetup
, decoder->frame_length, h_DecSetup->x_fl, h_DecSetup->scf_q,
&h_DecSetup->PlcSetup.nbLostCmpt, &h_DecSetup->PlcNsSetup.cum_alpha, bfi, &h_DecSetup->PlcSetup.prevBfi, &h_DecSetup->PlcSetup.prevprevBfi);
-
+
/* LTPF decoder */
process_ltpf_decoder_fl(h_DecSetup->x_fl, decoder->frame_length, h_DecSetup->x_fl, decoder->fs,
h_DecSetup->ltpf_mem_x, h_DecSetup->ltpf_mem_y, &h_DecSetup->ltpf_mem_pitch,
&h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ltpf_mem_gain, &h_DecSetup->ltpf_mem_beta_idx,
bfi, h_DecSetup->ltpf_param, h_DecSetup->ltpf_param_mem, h_DecSetup->ltpf_conf_beta_idx,
- h_DecSetup->ltpf_conf_beta, h_DecSetup->concealMethod, h_DecSetup->alpha
+ &h_DecSetup->ltpf_conf_beta, h_DecSetup->concealMethod, h_DecSetup->alpha
, &h_DecSetup->ltpf_mem_active
, &h_DecSetup->rel_pitch_change, decoder->hrmode, decoder->frame_dms
+#ifdef CR9_C_ADD_1p25MS
+ , &h_DecSetup->ltpf_mem_continuation, h_DecSetup->ltpf_param_mem_prev,
+ &h_DecSetup->ltpf_mem_pitch_prev, &h_DecSetup->ltpf_mem_pitch_fr_prev, &h_DecSetup->ltpf_mem_beta_idx_prev, &h_DecSetup->ltpf_mem_gain_prev,
+ &h_DecSetup->ltpf_pitch_stability_counter, &h_DecSetup->ltpf_gain_step, h_DecSetup->ltpf_conf_beta_max
+#endif
);
{
@@ -193,17 +264,18 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num
LC3_INT32 fec_num_bytes;
LC3_INT32 lc3_channel_num_bytes;
LC3_INT32 channel_bfi, out_bfi;
+ LC3_INT32 chan_error_report;
LC3PLUS_EpModeRequest channel_epmr;
-
+
bfi = bfi_ext;
lc3_num_bytes = 0;
err = LC3PLUS_OK;
-
+
if (bfi == 0)
{
bfi = !num_bytes;
}
-
+
if (decoder->ep_enabled)
{
decoder->combined_channel_coding = decoder->channels > 1 && num_bytes <= 160;
@@ -231,7 +303,7 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num
}
else
{
- decoder->channel_setup[ch]->last_size = lc3_channel_num_bytes;
+ decoder->channel_setup[ch]->last_size = lc3_channel_num_bytes;
}
}
@@ -246,20 +318,27 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num
{
decoder->epmr = LC3PLUS_EPMR_HIGH_NC;
out_bfi = 0;
+ decoder->error_report = 0;
for (ch = 0; ch < decoder->channels; ch++)
{
fec_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels));
- channel_bfi = bfi;
+ channel_bfi = bfi;
- decoder->error_report = fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &channel_epmr,
+ chan_error_report = fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &channel_epmr,
decoder->combined_channel_coding, &decoder->n_pccw, &channel_bfi,
&decoder->be_bp_left, &decoder->be_bp_right, &decoder->n_pc, &decoder->m_fec);
+
+ if (chan_error_report < 0 || decoder->error_report < 0) {
+ decoder->error_report = -1;
+ } else {
+ decoder->error_report += chan_error_report;
+ }
decoder->epmr = MIN((LC3PLUS_EpModeRequest) decoder->epmr, channel_epmr);
-
+
#ifdef ENABLE_PADDING
if (channel_bfi != 1)
{
@@ -274,9 +353,9 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num
{
input = input + np_zero;
}
-
+
decoder->n_pc = MAX(decoder->n_pc - (2 * np_zero), 0);
-
+
if (channel_bfi == 2)
{
if (decoder->be_bp_right < (8 * np_zero))
@@ -337,7 +416,7 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num
bfi = 1;
decoder->last_error = LC3PLUS_PADDING_ERROR;
}
-
+
lc3_num_bytes = lc3_num_bytes - padding_len;
if (lc3_num_bytes < 20 || lc3_num_bytes > LC3PLUS_MAX_BYTES)
{
@@ -345,8 +424,8 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num
decoder->last_error = FRAMESIZE_ERROR;
}
}
-#endif
-
+#endif
+
if (bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size)
{
err = update_dec_bitrate(decoder, ch, lc3_num_bytes);
diff --git a/lib_lc3plus/defines.h b/lib_lc3plus/defines.h
index 48c89f9ca02b2f2d25701b72b414fe54d168d58c..de7b1be260049947aa74718d612d532603f5e8c6 100644
--- a/lib_lc3plus/defines.h
+++ b/lib_lc3plus/defines.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -42,8 +42,52 @@ typedef uint32_t LC3_UINT32;
#ifndef NO_POST_REL_CHANGES
/* Post-release non-bitexact changes */
+#define CR13_B_FIX_PC_BINS
+#define CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+#define CR12_D_FIX_BITRATE_LIMITS
+
+#define CR9_C_ADD_1p25MS
+#ifdef CR9_C_ADD_1p25MS
+#define ENABLE_12p5_DMS_MODE
+#define CR9_C_ADD_1p25MS_LRSNS
+#define FIX_LTPF_PITCH_1p25
+
+#endif
+
#endif /* NO_POST_REL_CHANGES */
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+#define LRSNS_PC_SIGNAL_FIX /*correct handling of incoming bfi==2 to DEC_ENTROPY for conformance */
+#define LRSNS_10MS_BFISIGNAL_FIX /* correct signaling of detected BER in SNS/LRSNS */
+#define LRSNS_WMC_FIX
+/*#define LRSNS_CBC_NO_LTPF_DEPENDENCY */ /* turn off LRSNS CB_C dependency on LTPF activation flag */
+
+#define SNSLR_N_FIXENV 4 /* 4 fix envelopes multiplexed inside the full codeword */
+#define SNSLR_N_FIXENV_SHIFTS 4 /* 2 bits */
+#define SNSLR_MAX_PVQ_CAND 6 /* splitLF(0), full(1), fixed_env 2+{0,1,2,3 }, */
+#define SNSLR_MAX_PVQ_SEARCH_CAND (SNSLR_MAX_PVQ_CAND-SNSLR_N_FIXENV+1) /* 3 = splitLF(0), full(1), fixed_envs(2), */
+
+
+
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+#define LC3_CONST_FLOATMAX FLT_MAX
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+#undef SNS_VQ_MAX_IDX
+#define SNS_VQ_MAX_IDX 8
+
+#define SNSLR_NST1 170 /* 3*170 + 2 = 512 */
+#define SNSLR_NPVQ_L5K6 1970 /* mux into 11 bits 2048 pos , 78 slots remaining, 6 whole bits */
+#define SNSLR_NPVQ_L5K8 5890 /* additional split LF part muxed into 13 bits, log2(5980)= 12.5241 */
+#define SNSLR_NPVQ_L5K5 1002 /* mux into 10 bits 1024 pos , 22 slots remainging 4 whole bits */
+#define SNSLR_NPVQ_L8K2 128 /* 1+ 6 = 7 bits */
+#define SNSLR_NPVQ_L15K5 207006 /* 1+ 16.6593 bits */
+
+#endif
+
#define MAX_UINT8 255
#define THRESH_100_DMS_TDC_CNT 9
#define THRESH_100_DMS_NS_CNT 7
@@ -61,6 +105,68 @@ typedef uint32_t LC3_UINT32;
#define PLC_LONGTERM_ANALYSIS_MS 200 /* Analysis window 2000 ms / 10 ms */
#define PLC_LONGTERM_ANALYSIS_STARTUP_FILL 0.5f /* required buffer fill amount, set to 0.0 to not require any fill at all */
+
+
+#define SNS_IDX_LF 0
+#define SNS_IDX_HF 1
+#define SNS_IDX_SHAPEJ 2
+#define SNS_IDX_GAIN 3
+#define SNS_IDX_LS_INDA 4
+#define SNS_IDX_A 5
+#define SNS_IDX_BORGAINLSB 6
+
+#ifdef CR9_C_ADD_1p25MS
+
+/* master integration fixes for 1p25 */
+#define FIX_FLOAT_ENC_QUANTIZE_1P25MS_512KBPS /* add two last MDCT coeffs into the last quadruple for global_gain _energy_ analysis */
+#define FIX_FLOAT_LT_NORMCORR_INIT /*align state to BASOP start value of ~.5 as it has an effect on SNS_compute */
+
+#define FIX_BOTH_1p25_WB_GLOBGAINOFFSET_NONBE /* 1p25 curve tilt calulation corrected and made into BASOP */
+#define FIX_BOTH_1p25_WB_GLOBGAINOFFSET_LOWLIM_NONBE -135 /* 1p25 curve tilt calulation limited to value -135 kbps for NB&WB */
+#define FIX_BOTH_1p25_TEST_NEW_GG_EST2 /* GG_EST2_will use bands with two coeffs in each instead of four, for 1p25 WB and 1p25 SSWB , note only active for regular, hrmode==0 */
+
+#ifdef FIX_BOTH_1p25_TEST_NEW_GG_EST2
+#define FIX_BOTH_1p25_GG_EST_SWB_FB /* 1.25ms GG_EST update for SWB/FB, better RD curve float and BASOP , active for hrmode==0 */
+#endif
+
+/* defines to activate 2 or 3 tuple 1.25ms loops for all or any of WB,SSWB,SWB,FB */
+#define FIX_1p25_GG_EST_TUPLES /* 1.25 ms will use 2 or 3 tuples, note only active for regular, hrmode==0 */
+#ifdef FIX_1p25_GG_EST_TUPLES
+#define GG_1p25_WB_TUPLES 2
+#define GG_1p25_SSWB_TUPLES 2
+#define GG_1p25_SWB_TUPLES 2
+#define GG_1p25_FB_TUPLES 3
+#define GG_1p25_MAX_TUPLES MAX(MAX(GG_1p25_WB_TUPLES ,GG_1p25_SSWB_TUPLES ), MAX(GG_1p25_SWB_TUPLES ,GG_1p25_FB_TUPLES)) /* used to control common energy loop */
+
+#ifndef FIX_BOTH_1p25_ALLOC_SPECTRUM
+#define FIX_BOTH_1p25_ALLOC_SPECTRUM
+#endif
+
+#endif
+
+
+#define LTPF_ADAPTIVE_GAIN_RATE 20 /* Number of frames it must take to reach maximum beta from the default value, provided the pitch remains constant */
+#define LTPF_ADAPTIVE_GAIN
+
+#ifdef LTPF_ADAPTIVE_GAIN
+#define LTPF_PITCH_STABILITY_THRESHOLD 5 /* Number of frames for which the pitch must be constant for adaptive gain and pitch correction to be applied */
+#define LTPF_ADAPTIVE_GAIN_RATE 20 /* Number of frames it must take to reach maximum beta from the default value, provided the pitch remains constant */
+
+#define LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+#endif
+
+#ifdef CR9_C_ADD_1p25MS
+#define FIX_LTPF_MEM_CONTINUATION
+#define FIX_LTPF_PITCH_MEM_LEN
+#define FIX_PLC_CONFORM_ISSUES
+#define FIX_TDC_BURST_ERROR
+#define FIX_LTPF_DEC_FLFX_MISMATCH
+#define FIX_TX_RX_STRUCT_STEREO
+#define FIX_ADDITONAL_1p25_ISSUES
+#define NEW_SIGNALLING_SCHEME_1p25
+#define FIX_LTPF_1p25
+#endif
+#endif
/* Precision Defines */
#define LC3_FABS(x) (fabsf(x))
@@ -71,16 +177,23 @@ typedef uint32_t LC3_UINT32;
#define LC3_SIN(x) (sin(x))
#define LC3_SQRT(x) (sqrtf(x))
#define LC3_EXP(x) (expf(x))
+#define LC3_FMIN(x, y) (fminf(x, y))
+#define LC3_FMAX(x, y) (fmaxf(x, y))
-#define MAX_BR 320000 /* 400 * 800 */
-#define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */
-#define MIN_BR_025DMS 64000 /* 20 * 800 * 100/ 25 */
-#define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */
+#define MAX_BR 320000 /* 400 * 800 */
+#define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */
+#define MIN_BR_025DMS 64000 /* 20 * 800 * 100/ 25 */
+#define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */
#define MAX_BR_050DMS_NB 260800 /* 163 * 800 * 100/ 50 */
#define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */
#define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */
#define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */
+#ifdef CR9_C_ADD_1p25MS
+#define MIN_BR_0125DMS 128000 /* 20 * 800 * 100/ 12.5 */
+#define MAX_BR_0125DMS 512000
+#endif
+
#define MIN_BR_075DMS_48KHZ_HR ((int)124800/ 800/2)* 800
#define MIN_BR_075DMS_96KHZ_HR ((int)149600/ 800/2)* 800
#define MIN_BR_075DMS 21334 /* ceil( 20 * 800 * 100/ 75) */
@@ -148,8 +261,24 @@ typedef int32_t LC3_INT32;
#define PLC34_ATTEN_FAC_050 0.7071 /* attenuation factor for NS and TDC @ 5.0 ms*/
#define PLC34_ATTEN_FAC_025 0.8409 /* attenuation factor for NS and TDC @ 2.5 ms*/
+#ifdef CR9_C_ADD_1p25MS
+#define PLC34_ATTEN_FAC_0125 0.9995 /* attenuation factor for NS and TDC @ 1.25 ms*/
+#endif
+
#define FEC_SLOT_BYTES_MIN 40
#define FEC_SLOT_BYTES_MAX 400
+#ifdef CR12_D_FIX_BITRATE_LIMITS
+#ifdef ENABLE_HR_MODE_FL
+#define FEC_SLOT_BYTES_MIN_025DMS_48KHZ_HR 54
+#define FEC_SLOT_BYTES_MIN_025DMS_96KHZ_HR 61
+#define FEC_SLOT_BYTES_MIN_050DMS_48KHZ_HR 87
+#define FEC_SLOT_BYTES_MIN_050DMS_96KHZ_HR 101
+#define FEC_SLOT_BYTES_MIN_075DMS_48KHZ_HR 110
+#define FEC_SLOT_BYTES_MIN_075DMS_96KHZ_HR 126
+#define FEC_SLOT_BYTES_MIN_100DMS_48KHZ_HR 140
+#define FEC_SLOT_BYTES_MIN_100DMS_96KHZ_HR 164
+#endif
+#endif
#define LC3_CONST_POW_2_M15 3.051757812500000e-05
#define LC3_CONST_POW_2_23 8388608
@@ -166,13 +295,12 @@ typedef int32_t LC3_INT32;
#define G192_ONE 0x0081
#define READ_G192FER /* Allow C executable to also read G192 formatted FER files */
-#ifdef DEBUG
+#ifdef DEBUG
#ifdef READ_G192FER
-#define READ_G192_FER_BYTE /* Allow C executable to also read G192 byte formatted FER files 0x20=BAD , 0x21=Good */
+#define READ_G192_FER_BYTE /* Allow C executable to also read G192 byte formatted FER files 0x20=BAD , 0x21=Good */
#endif
#endif
-
#define LC3_EPS (1.1e-7f)
#define M_PI_LC3PLUS 3.14159265358979323846
@@ -221,6 +349,7 @@ typedef int32_t LC3_INT32;
#define MIN_BR_100MS_48KHZ_HR ((int)124800/800/2)*800
#define MIN_BR_100MS_96KHZ_HR ((int)149600/800/2)*800
#endif /* ENABLE_HR_MODE */
+
#define MAX_NBYTES2 625
#define BYTESBUFSIZE (MAX_NBYTES2 * MAX_CHANNELS)
#define MAX_BW_BIN 400
@@ -245,8 +374,21 @@ typedef int32_t LC3_INT32;
7 /* (L+H) + submode_MSB +gain+(Ia_leads+Ia_mpvq)+(Ib_joint_mpvq), \
submode-LSB */
-/* RESIDUAL CODING */
-#define NPRM_RESQ 5 * MAX_LEN
+#ifdef CR9_C_ADD_1p25MS
+#undef SNS_VQ_MAX_IDX
+#define SNS_VQ_MAX_IDX 8
+
+#define SNSLR_NST1 170 /*, 3*170 + 2 = 512 */
+#define SNSLR_NPVQ_L5K6 1970 /* mux into 11 bits 2048 pos , 78 slots remaining, 6 whole bits */
+#define SNSLR_NPVQ_L5K5 1002 /* mux into 10 bits 1024 pos , 22 slots remainging 4 whole bits */
+#define SNSLR_NPVQ_L8K2 128 /* 1+6 = 7 bits */
+#define SNSLR_NPVQ_L15K5 207006 /* 1+ 16.6593 bits , */
+
+#define SNSLR_ST1_SCALEC (round(1.5*16384.0)/16384.0 ) /* SNS_ST1_SCALEC 1.5 in Q1.14 */
+#define SNSLR_ST1_INVSCALEC (round((2.0/3.0)*(32768.0))/32768.0) /* SNSLR_ST1_INVSCALEC 0.66667 in Q0.15 */
+
+#endif /* CR9_C_ADD_1p25MS */
+
/* MDCT */
#define MDCT_MEM_LEN_MAX (MAX_LEN - ((180 * MAX_LEN) / 480))
@@ -266,7 +408,11 @@ typedef int32_t LC3_INT32;
#define RES2_PITCH_12K8 157
#define RES4_PITCH_12K8 127
#define LTPF_MEMIN_LEN (MAX_PITCH_12K8 + 4)
-
+#ifdef CR9_C_ADD_1p25MS
+#define LEN_MEM_NORMCORR 5
+#else
+#define LEN_MEM_NORMCORR 2
+#endif
/* Advanced PLC */
diff --git a/lib_lc3plus/detect_cutoff_warped.c b/lib_lc3plus/detect_cutoff_warped.c
index 4005c68e74446270079ca0028b4c41d5fda2a5ee..f5ccc45ed69d2471a5a09fe5570b2665815063e3 100644
--- a/lib_lc3plus/detect_cutoff_warped.c
+++ b/lib_lc3plus/detect_cutoff_warped.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,7 +11,7 @@
#include "wmc_auto.h"
#include "functions.h"
-void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx)
+void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3PLUS_FrameDuration frame_dms, LC3_INT* bw_idx)
{
const LC3_INT *warp_idx_start, *warp_idx_stop;
LC3_INT counter, brickwall = 0, i, stop, dist;
@@ -23,26 +23,33 @@ void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_d
switch (frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ assert (0);
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
warp_idx_start = BW_warp_idx_start_all_2_5ms[fs_idx - 1];
warp_idx_stop = BW_warp_idx_stop_all_2_5ms[fs_idx - 1];
bw_dist = brickwall_dist;
break;
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
warp_idx_start = BW_warp_idx_start_all_5ms[fs_idx - 1];
warp_idx_stop = BW_warp_idx_stop_all_5ms[fs_idx - 1];
bw_dist = brickwall_dist;
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
warp_idx_start = BW_warp_idx_start_all_7_5ms[fs_idx - 1];
warp_idx_stop = BW_warp_idx_stop_all_7_5ms[fs_idx - 1];
bw_dist = brickwall_dist_7_5ms;
break;
- case 100:
+ case LC3PLUS_FRAME_DURATION_10MS:
warp_idx_start = BW_warp_idx_start_all[fs_idx - 1];
warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1];
bw_dist = brickwall_dist;
break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
counter = fs_idx;
diff --git a/lib_lc3plus/enc_entropy.c b/lib_lc3plus/enc_entropy.c
index 28e3cea69cde99ee361c6d6701aca9556ec09866..51f9ddb1bfee2874f6d29bfc9b0cc63477430ff7 100644
--- a/lib_lc3plus/enc_entropy.c
+++ b/lib_lc3plus/enc_entropy.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,21 +11,352 @@
#include "wmc_auto.h"
#include "functions.h"
-static const LC3_INT gainMSBbits[4] = {1, 1, 2, 2};
-static const LC3_INT gainLSBbits[4] = {0, 1, 0, 1};
+#ifdef CR9_C_ADD_1p25MS
+
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+void writeLtpData_fl( LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT32* ltpf_idx, LC3_INT16* Tx_ltpf );
+#endif
+
+void writeSNSData_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3PLUS_FrameDuration frame_dms, LC3_INT32* scf_idx);
+#else /* CR9_C_ADD_1p25MS */
+void writeSNSData_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT32* scf_idx);
+#endif /* CR9_C_ADD_1p25MS */
+
+
+static const LC3_INT32 gainMSBbits[4] = {1, 1, 2, 2};
+static const LC3_INT32 gainLSBbits[4] = {0, 1, 0, 1};
+
+
+#ifdef CR9_C_ADD_1p25MS
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+void writeLtpData_fl(
+ LC3_UINT8* ptr,
+ LC3_INT* bp_side,
+ LC3_INT* mask_side,
+ LC3_INT32* ltpf_idx,
+ LC3_INT16* Tx_ltpf
+)
+{
+ LC3_INT32 tmp;
+ LC3_INT32 bitsTx;
+ /* Hdr, information , bits used
+ 00 , no lag info , no phase info sum=2
+ 010, PhaseA,LTPF=0, lagAbits=4 , sum=7 : pitch-PLC may be activated with old lag , 4 MSbs
+ 011, PhaseB,LTPF=0, lagBbits=4*, sum=7* : pitch-PLC may be activated with fresh lag, 4* = reduced lag resolution in Quantized ltpf_idx domain for PLC
+ 10 , PhaseA,LTPF=1, lagAbits=4 , sum=6 : LTPF may be activated with old lag
+ 11 , PhaseB,LTPF=1, lagBbits=5 , sum=7 : LTPF activated with fresh lag
+*/
+
+
+ tmp = MIN(*Tx_ltpf, 1); /*phaseA==0, phaseB==1*/
+
+ if (ltpf_idx[0] == 0)
+ {
+ write_bit_backward_fl(ptr, bp_side, mask_side, 0); /* "00" */
+ write_bit_backward_fl(ptr, bp_side, mask_side, 0);
+
+ *Tx_ltpf = 0;
+ /* *Tx_ltpf A/B state forced to zero or kept at zero */
+ /* decoder will discard any sofar in phase received phaseA MSB bits */
+ }
+ else if (ltpf_idx[1] == 0)
+ {
+ /* no current LTPF activation,
+ lag transmitted for PLC, or for next frame LTPF activation */
+ assert(ltpf_idx[0] != 0);
+
+ /* A "010" 3 bits Hdr transmitted */
+ /* B "011" 3 bits Hdr transmitted*/
+
+ write_uint_backward_fl(ptr, bp_side, mask_side, 1, 2); /* "01"*/
+ write_bit_backward_fl(ptr, bp_side, mask_side, tmp); /* phase A or phaseB */
+
+ if (*Tx_ltpf == 0)
+ { /* phase A transmission */
+ assert(tmp == 0);
+ assert((ltpf_idx[2] & ~(0x01ff)) == 0); /* only 9 bits info allowed within ltpf_idx[2] */
+ tmp = (ltpf_idx[2] >> 5 ); /* shift_out LSBS, send 4 MSBs */
+ *Tx_ltpf = (0x200 | ltpf_idx[2]); /* remember full lag, as phaseB sentinel in bit 10, */
+ }
+ else
+ { /* phase B */
+ assert(tmp == 1);
+ assert(*Tx_ltpf > 511); /*sentinel in b10 should have been set in previous phaseA frame */
+ tmp = ((*Tx_ltpf & 0x001f) >> 1); /* B send 4* LSBs, 1 bit truncated */
+ *Tx_ltpf = 0; /* clear sentinel in b10 and the old remebered lag value */
+ }
+ write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 4); /* 4 bits lag info Tx, when LTPF is deactivated */
+ }
+ else
+ { /* LTPF activated */
+ /* A "10" 2 bits Hdr */
+ /* B "11" 2 bits Hdr */
+ assert(ltpf_idx[0] != 0 && ltpf_idx[1] != 0);
+
+ tmp |= 0x02;
+ write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 2);
+
+ if (*Tx_ltpf == 0)
+ {
+ bitsTx = 4;
+ assert((ltpf_idx[2] & ~(0x01ff)) == 0); /* only 9 bits info allowed within ltpf_idx[2] */
+ tmp = (ltpf_idx[2] >> 5); /* shift away 5 LBS, LTPF active, send phaseA 4 MSBs */
+
+ *Tx_ltpf = 0x0200 | ltpf_idx[2]; /* remember full lag in state *Tx_ltpf, add phaseB Tx state sentinel in bit 10 */
+ }
+ else
+ {
+ bitsTx = 5;
+ tmp = (*Tx_ltpf & 0x001f); /* LTPF active B send 5 LSBs , full regular resolution */
+ *Tx_ltpf = 0; /* clear sentinel in b10 and also the old remebered lag value */
+ }
+
+ write_uint_backward_fl(ptr, bp_side, mask_side, tmp, bitsTx); /* ltp==1 , ltpf==1, 4(A,MSBs) or 5(b, LSBs) bits */
+ }
+}
+#endif /* NEW_SIGNALLING_SCHEME_1p25 */
+void writeSNSData_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3PLUS_FrameDuration frame_dms, LC3_INT32* scf_idx)
+#else
+void writeSNSData_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT32* scf_idx)
+#endif
+{
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+
+ LC3_INT32 submodeMSB, submodeLSB, tmp, gainMSB, gainLSB;
+ LC3_INT16 write_legacy_sns_vq_bits;
+ LC3_INT32 aux_idx;
+ LC3_INT32 shape_idx;
+ LC3_INT32 env_shape_idx;
+ LC3_INT32 gain_idx;
+ LC3_INT16 n5k;
+
+#else
+ LC3_INT32 submodeMSB, submodeLSB, tmp, gainMSB, gainLSB;
+#endif
+
+#if defined(CR9_C_ADD_1p25MS) && !defined( CR9_C_ADD_1p25MS_LRSNS)
+UNUSED(frame_dms);
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ write_legacy_sns_vq_bits = 1;
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) /* 9,10,29/30 */
+ {
+ write_legacy_sns_vq_bits = 0;
+ }
+ if (write_legacy_sns_vq_bits != 0)
+ {
+#endif
+ /* SNS-VQ 1st stage */
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[0], 5);
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[1], 5);
+
+ /* SNS-VQ 2nd stage side-info (3-4 bits) */
+ submodeMSB = scf_idx[2] / 2;
+ submodeLSB = scf_idx[2] & 1;
+ write_bit_backward_fl(ptr, bp_side, mask_side, submodeMSB);
+ gainMSB = scf_idx[3] >> (gainLSBbits[scf_idx[2]]);
+ gainLSB = scf_idx[3] & 1;
+ write_uint_backward_fl(ptr, bp_side, mask_side, gainMSB, gainMSBbits[scf_idx[2]]);
+ write_bit_backward_fl(ptr, bp_side, mask_side, scf_idx[4]);
+
+ /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */
+ if (submodeMSB == 0)
+ {
+ if (submodeLSB == 0)
+ {
+ tmp = scf_idx[6] + 2;
+ }
+ else
+ {
+ tmp = gainLSB;
+ }
+
+ tmp = tmp * 2390004 + scf_idx[5];
+ write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 25);
+ }
+ else
+ {
+ tmp = scf_idx[5];
+
+ if (submodeLSB != 0)
+ {
+ tmp = 2 * tmp + gainLSB + 15158272;
+ }
+ write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 24);
+ }
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ }
+ if (write_legacy_sns_vq_bits == 0)
+ {
+ /* SNS-VQ 1st stage is jointly multiplexed into 9 bits or 10 bits */
+ /* input scf_idx[0], has the stage1 index for one of BCA or B* */
+ aux_idx = scf_idx[1]; /* aux value: we have the LS, or the s0 sign bit */
+ shape_idx = scf_idx[2]; /* st2 shape 0 .. 5 , where [2.3.4.5] are fixed FESS shapes */
+ gain_idx = scf_idx[3]; /* idx of 2-3 bits valued gains */
+
+ if (shape_idx == 0 && scf_idx[0] >= 0)
+ { /*aux==2 --> split mode st1B (aux==2), + a 2 bit gain + P(5,6)10.96b + P(8,2)7b */
+ assert(shape_idx == 0 && gain_idx < 4);
+ }
+ if ((shape_idx == 1) && scf_idx[0] >= 0)
+ { /* regular mode st1B , + a 3 bit gain + P(15,5) */
+ assert(shape_idx == 1 && gain_idx >= 0 && gain_idx < 8);
+ }
+ if ((shape_idx >= 2) && scf_idx[0] >= 0)
+ { /* regular mode st1B , + a 3 bit gain + fixenv */
+ assert(shape_idx >= 2 && shape_idx <= 5 && gain_idx >= 0 && gain_idx < 8);
+ }
+
+ /* b0-b8 b9
+ segm , idx9b , stop bit, comment use
+ -----+--------+---------
+ A | 510,511| n/a, 2 entries, 9 bit total
+ ------+--------+--------
+ B | 0--169 | 1 , 170 entries, 10 bit total
+ ------+--------+--------
+ C | 170-339| 1 , 170 entries, 10 bit total
+ ------+--------+--------+------------
+ */
+
+ if (scf_idx[0] >= 510)
+ { /* stage1A */
+ assert(scf_idx[0] < (1 << 9));
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[0], 9); /* currently writes 510 or 511 */
+ shape_idx = -9; /* only crude stage 1 A , no more bits to send */
+ }
+ else if ( (scf_idx[0] < 2 * 170) && (shape_idx < 0) )
+ {
+ if (scf_idx[0] < 170)
+ {
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[0] + 0 * 170, 9); /* 1B */
+ }
+ else if (scf_idx[0] < 2 * 170)
+ {
+ write_uint_backward_fl(ptr, bp_side, mask_side, (scf_idx[0] - 170) + 1 * 170, 9); /* 1C */
+ }
+ /* write the stop bit value sentinel value "1", so that the demux dec_entropy can stop already at (9+1)=10 bits */
+
+ write_uint_backward_fl(ptr, bp_side, mask_side, 1, 1); /* dec_entropy will read a 1 "stop" bit */
+
+ /* pitch_rx and ltpf_rx handled separately */
+ }
+ else if (shape_idx == 0)
+ {
+ /* aux info as a part of (9+1) 10 initial bits */
+ /* b0-b8 b9
+ segm , idx9b , stop bit, comment use
+ -----+--------+---------
+ B* | 0--169 | 0 , --> aux=0, 170, 2b+17b for stage2 'LR_SplitLF', 29 bit total
+ ------+--------+--------+-------
+ B* | 170-339| 0 , --> aux=1, 170, 2b+17b for stage2 'LR_SplitLF', 29 bit total
+ ------+--------+--------+-------
+ */
+ /* 29 bit total LR_splitLF */
+ assert(scf_idx[0] >= 0 && scf_idx[0] < 170); /* st1B range */
+ assert(aux_idx >= 0 && aux_idx <= 1); /* aux_bit can only be 1 or 0 */
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[0] + aux_idx * 170, 9); /* aux_bit defined by region 0..339 region in decoder */
+ write_uint_backward_fl(ptr, bp_side, mask_side, 0, 1); /* "stop" bit. always zero for 'LR_splitLF' */
+
+ write_uint_backward_fl(ptr, bp_side, mask_side, gain_idx, 2); /* always 2bits == 4 gain levels for the splitLF mode */
+
+ n5k = 6;
+ if (scf_idx[5] < 0) {
+ assert(scf_idx[5] == -8 );
+ n5k = 8;
+ }
+
+ if (n5k == 6)
+ { /* multiplex remaining 10 + 1+6 bit */
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[4], 10); /* 29b P(5,6)=10.94 in LS+10 bits, */
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[5] & 0x1, 1); /* LS for P(8,2)=7 */
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[5] >> 1, 6); /* mPVQ(8,2) in 6 */
+ }
+ else
+ { /* LF is PVQ(N=5,K=8), HF is all zero , multiplexed as top section in stage2 10b , + 7b */
+ /* scf_idx[4] is in the range [0 ... (SNSLR_NPVQ_L5K8 >>1)[, [0 .. 2945[ , 11.52 bits */
+ /* 985 - 1024 = 39 entries where we now use only 32 (5 bits) */
+ /* index_to_send = (SNSLR_NPVQ_L5K6 >> 1) + (scf_idx[4] & 0x001f) , range [985 .. 1017[ , i.e. 7 values are not sent:[1018 ... 1023] */
+ write_uint_backward_fl(ptr, bp_side, mask_side, (SNSLR_NPVQ_L5K6 >> 1) + (scf_idx[4] & 0x001f), 10); /* 5 lsb's as top in the 10b */
+ assert((scf_idx[4] >> 5) < (1 << 7));
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[4] >> 5, 7); /* 7 msb's of mpvq(5,8)*/
+ }
+ }
+ else if (shape_idx == 1)
+ {
+ /* b0-b8 b9
+ segm , idx9b , stop bit, comment use
+ ------+--------+--------+------------
+ B* | 340-509| 1 --> aux=1, 170, 3b+17b for stage2 'LR_full', 30 bit total
+ ------+--------+--------+-------
+ B* | 340-509| 0 --> aux=0, 170, 3b+17b for stage2 'LR_full', 30 bit total
+ ------+--------+--------+-------
+ */
+ assert(scf_idx[0] >= 0 && scf_idx[0] < 170); /* st1B* range */
+
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[0] + 2 * 170, 9); /* stage1B* signal */
+ write_uint_backward_fl(ptr, bp_side, mask_side, aux_idx, 1); /* auxbit transmitted in the stop bit location */
+
+ write_uint_backward_fl(ptr, bp_side, mask_side, gain_idx, 3); /*30b always 8 gain levels in 3 bits for the full mode */
+ /* the next 17 bit index is used to decode submode 1==full or one of submode 2,3,4,5 == fix */
+ assert(scf_idx[4] >= 0 && scf_idx[4] < ((SNSLR_NPVQ_L15K5 >> 1)));
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[4], 17); /* P(15,5) without the leading sign, 16.6593 bits, written */
+ }
+ else
+ { /* Fixed shapes 2(ones, env0) and 3(env1) , 4(env2), and later 5(env3) */
+ assert(shape_idx >= 2 && shape_idx <= 5);
+ /* env 0,1,2, : s0(in aux) + shift(2bits)+ 11 signs , section size 8192
+ env 3 : s0(in aux) + shift(2bits)+ 9 signs , section size 2048
+ */
+ env_shape_idx = scf_idx[4];
+ assert(env_shape_idx == (shape_idx - 2)); /*scf_idx[4] has the fixed env index*/
+
+ assert(scf_idx[0] >= 0 && scf_idx[0] < 170); /* st1B* range */
+
+ write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[0] + 2 * 170, 9); /* stage1B* signal */
+ write_uint_backward_fl(ptr, bp_side, mask_side, aux_idx, 1); /* auxbit transmitted in the stop bit location */
+
+ write_uint_backward_fl(ptr, bp_side, mask_side, gain_idx, 3); /* for 30bit its is always 3 gain bits */
+
+ if (shape_idx < 5) /*2,3,4*/
+ {
+ assert(scf_idx[5] >= 0 && scf_idx[5] < (1 << 13));
+ assert((SNSLR_NPVQ_L15K5 >> 1) + env_shape_idx * (1 << 13) + scf_idx[5] < (1 << 17));
+ /* offset is PVQ(15,5) without leading sign */
+ /* int32_t tmp_idx = (SNSLR_NPVQ_L15K5 >> 1) + env_shape_idx * (1 << 13) + scf_idx[5]; */
+ write_uint_backward_fl(ptr, bp_side, mask_side, (SNSLR_NPVQ_L15K5 >> 1) + env_shape_idx * (1 << 13) + scf_idx[5], 17);
+ }
+ else
+ {
+ assert(shape_idx == 5);
+ assert(env_shape_idx == 3);
+ assert(scf_idx[5] < (1 << 11));
+ assert(((SNSLR_NPVQ_L15K5 >> 1) + 3 * (1 << 13) + scf_idx[5]) < (1 << 17));
+ /* offset is (15,5) without leading sign */
+ write_uint_backward_fl(ptr, bp_side, mask_side, (SNSLR_NPVQ_L15K5 >> 1) + 3 * (1 << 13) + scf_idx[5], 17);
+ }
+ }
+ }
+#endif
+}
void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT numbytes, LC3_INT bw_cutoff_bits,
LC3_INT bw_cutoff_idx, LC3_INT lastnz, LC3_INT N, LC3_INT lsbMode, LC3_INT gg_idx, LC3_INT num_tns_filters,
- LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* scf_idx, LC3_INT fac_ns_idx
- , LC3_INT bfi_ext, LC3_INT fs_idx
+ LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* scf_idx, LC3_INT fac_ns_idx,
+ LC3_INT bfi_ext, LC3_INT fs_idx
+#ifdef CR9_C_ADD_1p25MS
+ , LC3PLUS_FrameDuration frame_dms, LC3_INT16* Tx_ltpf
+#endif
)
{
LC3_UINT8* ptr;
- LC3_INT i, submodeMSB, submodeLSB, tmp, gainMSB, gainLSB;
+ LC3_INT i;
-
LC3_INT16 lastnzTrigger[5] = {63, 127, 127, 255, 255};
+#if defined(CR9_C_ADD_1p25MS) && !defined(CR9_C_ADD_1p25MS_LRSNS)
+ UNUSED(Tx_ltpf);
+#endif
*bp_side = numbytes - 1;
*mask_side = 1;
ptr = bytes;
@@ -37,11 +368,11 @@ void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_
/* Last non zero touple */
if (bfi_ext == 1) {
- write_uint_backward_fl(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], ceil(LC3_LOGTWO(N >> 1)));
+ write_uint_backward_fl(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], getLastNzBits (N));
}
else
{
- write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N >> 1)));
+ write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, getLastNzBits (N));
}
/* LSB mode bit */
@@ -56,46 +387,43 @@ void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_
}
/* LTPF activation flag */
+#ifdef CR9_C_ADD_1p25MS
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ writeLtpData_fl(ptr, bp_side, mask_side, ltpf_idx, Tx_ltpf); /* LTP and LTPF-active and interleaved lag-idx */
+ }
+ else
+ {
+ write_bit_backward_fl(ptr, bp_side, mask_side, ltpf_idx[0]); /* ltp tx bit */
+ }
+#endif
+#else
write_bit_backward_fl(ptr, bp_side, mask_side, ltpf_idx[0]);
+#endif /* CR9_C_ADD_1p25MS */
- /* SNS-VQ 1st stage */
- write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[0], 5);
- write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[1], 5);
-
- /* SNS-VQ 2nd stage side-info (3-4 bits) */
- submodeMSB = scf_idx[2] / 2;
- submodeLSB = scf_idx[2] & 1;
- write_bit_backward_fl(ptr, bp_side, mask_side, submodeMSB);
- gainMSB = scf_idx[3] >> (gainLSBbits[scf_idx[2]]);
- gainLSB = scf_idx[3] & 1;
- write_uint_backward_fl(ptr, bp_side, mask_side, gainMSB, gainMSBbits[scf_idx[2]]);
- write_bit_backward_fl(ptr, bp_side, mask_side, scf_idx[4]);
-
- /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */
- if (submodeMSB == 0) {
- if (submodeLSB == 0) {
- tmp = scf_idx[6] + 2;
- } else {
- tmp = gainLSB;
- }
-
- tmp = tmp * 2390004 + scf_idx[5];
- write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 25);
- } else {
- tmp = scf_idx[5];
-
- if (submodeLSB != 0) {
- tmp = 2 * tmp + gainLSB + 15158272;
- }
-
- write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 24);
- }
+ /* SNS data*/
+#ifdef CR9_C_ADD_1p25MS
+ writeSNSData_fl(ptr, bp_side, mask_side, frame_dms, scf_idx);
+#else
+ writeSNSData_fl(ptr, bp_side, mask_side, scf_idx);
+#endif
/* LTPF data */
+#ifdef CR9_C_ADD_1p25MS
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ if ((frame_dms != LC3PLUS_FRAME_DURATION_1p25MS ) && (ltpf_idx[0] == 1) )
+ {
+ write_uint_backward_fl( ptr, bp_side, mask_side, ltpf_idx[1], 1 );
+ write_uint_backward_fl( ptr, bp_side, mask_side, ltpf_idx[2], 9 );
+ }
+#endif
+#else /* CR9_C_ADD_1p25MS */
if (ltpf_idx[0] == 1) {
write_uint_backward_fl(ptr, bp_side, mask_side, ltpf_idx[1], 1);
write_uint_backward_fl(ptr, bp_side, mask_side, ltpf_idx[2], 9);
}
+#endif /* CR9_C_ADD_1p25MS */
/* Noise factor */
write_uint_backward_fl(ptr, bp_side, mask_side, fac_ns_idx, 3);
diff --git a/lib_lc3plus/enc_lc3_fl.c b/lib_lc3plus/enc_lc3_fl.c
index 0729df98dcdff9450f4ab2a418f055eb2d940a31..7d2ec43d326012e73c520c3f6094d53f8df5be17 100644
--- a/lib_lc3plus/enc_lc3_fl.c
+++ b/lib_lc3plus/enc_lc3_fl.c
@@ -1,16 +1,20 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
* estoppel or otherwise. *
******************************************************************************/
-
+
#include "options.h"
#include "wmc_auto.h"
#include "functions.h"
+#ifdef FIX_BOTH_1p25_ALLOC_SPECTRUM
+#include
+#endif
+
static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s_in, uint8_t* bytes, int bps
, LC3_INT32 bfi_ext
)
@@ -21,15 +25,28 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s
quantizedGainMin = 0, nbits = 0, nbits2 = 0, lastnz = 0, lsbMode = 0, gainChange = 0, bp_side = 0,
mask_side = 0, fac_ns_idx = 0, numResBits = 0, tns_order[2] = {0}, i = 0;
LC3_FLOAT normcorr = 0, gain = 0;
-
LC3_FLOAT d_fl[MAX_LEN] = {0};
LC3_INT q_d[MAX_LEN] = {0};
LC3_INT indexes[TNS_NUMFILTERS_MAX * MAXLAG] = {0};
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ LC3_INT16 envelope_bits = -1;
+ LC3_INT32 pitch_rx = -1; /* pitch_rx status flag */
+ LC3_INT32 ltpf_rx = -1;
+#endif
+
h_EncSetup = encoder->channel_setup[channel];
memset(bytes, 0, sizeof(uint8_t) * h_EncSetup->targetBytes);
+#ifdef FIX_BOTH_1p25_ALLOC_SPECTRUM
+ if (encoder->frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ assert(MAX_LEN >= (GG_1p25_MAX_TUPLES - 1) + (encoder->yLen));
+ /*make sure that there extra tail coeffs in d_fl for Global gain estimation routine */
+ }
+#endif
+
if (bps == 24) {
for (i = 0; i < encoder->frame_length; i++) {
int32_t tmp = ((int32_t*)s_in)[i];
@@ -62,17 +79,33 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s
/* Pitch estimation */
processOlpa_fl(h_EncSetup->s_12k8, h_EncSetup->olpa_mem_s12k8, h_EncSetup->olpa_mem_s6k4,
- &h_EncSetup->olpa_mem_pitch,
- &h_EncSetup->pitch_flag,
+ &h_EncSetup->olpa_mem_pitch,
+ &h_EncSetup->pitch_flag,
&T0_out, &normcorr, s_12k8_len, encoder->frame_dms);
/* LTPF encoder */
process_ltpf_coder_fl(h_EncSetup->s_12k8, s_12k8_len + 1, h_EncSetup->ltpf_enable, T0_out, normcorr,
encoder->frame_dms, h_EncSetup->ltpf_mem_in, encoder->ltpf_mem_in_len,
- &h_EncSetup->ltpf_mem_normcorr, &h_EncSetup->ltpf_mem_ltpf_on,
+#ifdef CR9_C_ADD_1p25MS
+ h_EncSetup->ltpf_mem_normcorr,
+#else
+ &h_EncSetup->ltpf_mem_normcorr,
+#endif
+ &h_EncSetup->ltpf_mem_ltpf_on,
&h_EncSetup->ltpf_mem_pitch, h_EncSetup->ltpf_param, &h_EncSetup->ltpf_mem_mem_normcorr,
<pfBits
, encoder->hrmode
+#ifdef CR9_C_ADD_1p25MS
+#ifdef FIX_TX_RX_STRUCT_STEREO
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ ,&h_EncSetup->Tx_ltpf
+#else
+ ,h_EncSetup->Tx_ltpf
+#endif
+#else
+ , encoder->Tx_ltpf
+#endif
+#endif
);
/* Attack detector */
@@ -83,8 +116,8 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s
/* Per-band energy */
processPerBandEnergy_fl(encoder->bands_number, encoder->bands_offset, encoder->hrmode, encoder->frame_dms, h_EncSetup->ener, d_fl);
/* Near Nyquist detector */
- processNearNyquistdetector_fl(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, encoder->bands_number, h_EncSetup->ener
- , encoder->frame_dms, encoder->hrmode );
+ processNearNyquistdetector_fl(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, encoder->bands_number, h_EncSetup->ener
+ , encoder->frame_dms, encoder->hrmode );
/* Disable LTPF if nyquist detector triggers or -lfe mode is active*/
if (encoder->near_nyquist_flag != 0 || h_EncSetup->lfe == 1)
{
@@ -105,25 +138,52 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s
}
processSnsComputeScf_fl(h_EncSetup->ener, encoder->bands_number, h_EncSetup->scf,
- h_EncSetup->attdec_detected, encoder->sns_damping, encoder->attdec_damping, encoder->fs_idx);
+ h_EncSetup->attdec_detected, encoder->sns_damping, encoder->attdec_damping, encoder->fs_idx
+#ifdef CR9_C_ADD_1p25MS
+ , encoder->frame_dms, &encoder->long_term_norm_corr, normcorr
+#endif
+ );
/* SNS Quantizer */
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ if (encoder->frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ /* 9,10, 29,30 bit LRSNS quantizer */
+ pitch_rx = h_EncSetup->ltpf_param[0]; /* pitch_rx status flag */
+ ltpf_rx = h_EncSetup->ltpf_param[1]; /* ltpf active flag, LTPF lag data information is split over two 1.25 ms frames */
+ assert(ltpfBits == 2 || ltpfBits == 6 || ltpfBits == 7);
+ assert((pitch_rx != 0 && ltpf_rx == 0) || (pitch_rx != 0 && ltpf_rx != 0) || (pitch_rx == 0 && ltpf_rx == 0));
+
+ envelope_bits = snsQuantScfEncLR(h_EncSetup->scf, h_EncSetup->L_scf_idx, h_EncSetup->scf_q, h_EncSetup->dct2StructSNS, pitch_rx, ltpf_rx);
+ }
+ else
+ { /* legacy 38 bit SNS VQ */
+ assert(ltpfBits == 1 || ltpfBits == 11);
+ process_snsQuantizesScf_Enc(h_EncSetup->scf, h_EncSetup->L_scf_idx, h_EncSetup->scf_q, h_EncSetup->dct2StructSNS);
+ envelope_bits = 38;
+ }
+#else
process_snsQuantizesScf_Enc(h_EncSetup->scf, h_EncSetup->L_scf_idx, h_EncSetup->scf_q, h_EncSetup->dct2StructSNS);
+#endif
/* SNS Interpolation */
processSnsInterpolateScf_fl(h_EncSetup->scf_q, 1, encoder->bands_number, h_EncSetup->int_scf);
/* MDCT shaping */
processMdctShaping_fl(d_fl, h_EncSetup->int_scf, encoder->bands_offset, encoder->bands_number);
-
+
/* Bandwidth controller */
if (encoder->bandwidth < encoder->fs / 2) {
process_cutoff_bandwidth(d_fl, encoder->yLen, encoder->bw_ctrl_cutoff_bin);
BW_cutoff_idx = MIN(BW_cutoff_idx, encoder->bw_index);
}
-
+
/* TNS encoder */
+#ifdef CR9_C_ADD_1p25MS
+ if (h_EncSetup->lfe == 0 && encoder->frame_dms > LC3PLUS_FRAME_DURATION_1p25MS)
+#else
if (h_EncSetup->lfe == 0)
+#endif
{
processTnsCoder_fl(d_fl, BW_cutoff_idx, encoder->cutoffBins[BW_cutoff_idx], encoder->fs, encoder->frame_length,
encoder->frame_dms, h_EncSetup->total_bits, tns_order, indexes, &tns_numfilters,
@@ -134,20 +194,25 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s
else
{
tns_numfilters = 1;
+#ifdef CR9_C_ADD_1p25MS
+ if (encoder->frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ tns_numfilters = 0;
+ }
+#endif
tns_order[0] = 0;
h_EncSetup->tns_bits = tns_numfilters;
}
/* Global Gain Estimation */
h_EncSetup->targetBitsQuant = h_EncSetup->targetBitsInit - (h_EncSetup->tns_bits + ltpfBits);
- if (h_EncSetup->targetBitsQuant < 0 && ltpfBits > 1)
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ if ( encoder->frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
{
- /* Disable LTPF */
- h_EncSetup->ltpf_mem_ltpf_on = 0;
- h_EncSetup->ltpf_param[1] = 0;
- ltpfBits = 1;
- h_EncSetup->targetBitsQuant = h_EncSetup->targetBitsInit - (h_EncSetup->tns_bits + ltpfBits);
+ h_EncSetup->targetBitsQuant += 38; /* 38 was already subtracted in h_EncSetup->targetBitsInit setup */
+ assert(envelope_bits >= 9 && envelope_bits <= 30);
+ h_EncSetup->targetBitsQuant -= envelope_bits; /* 9,10, 29,30 */
}
+#endif
processEstimateGlobalGain_fl(d_fl, encoder->yLen, h_EncSetup->targetBitsQuant, &gain, &quantizedGain,
&quantizedGainMin, h_EncSetup->quantizedGainOff, &h_EncSetup->targetBitsOff,
@@ -173,7 +238,7 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s
if (gainChange) {
processQuantizeSpec_fl(d_fl, gain, q_d, encoder->yLen, h_EncSetup->total_bits, &nbits, &nbits2, encoder->fs,
&lastnz,
- h_EncSetup->codingdata,
+ h_EncSetup->codingdata,
&lsbMode, 0, h_EncSetup->targetBitsQuant
, encoder->hrmode
);
@@ -181,10 +246,9 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s
/* Noise factor */
if (h_EncSetup->lfe == 0)
- {
- processNoiseFactor_fl(&fac_ns_idx, d_fl, q_d, gain, encoder->cutoffBins[BW_cutoff_idx], encoder->frame_dms,
- h_EncSetup->targetBytes
- );
+ {
+ processNoiseFactor_fl(&fac_ns_idx, d_fl, q_d, gain, encoder->cutoffBins[BW_cutoff_idx], encoder->frame_dms,
+ h_EncSetup->targetBytes);
}
else
{
@@ -192,9 +256,10 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s
}
/* Residual Coding */
if (lsbMode == 0) {
- processResidualCoding_fl(d_fl, q_d, gain, encoder->yLen, h_EncSetup->targetBitsQuant, nbits2,
- h_EncSetup->resBits, &numResBits
- , encoder->hrmode
+ processResidualCoding_fl(d_fl, q_d, gain, encoder->yLen, h_EncSetup->targetBitsQuant, nbits2, h_EncSetup->resBits, &numResBits, encoder->hrmode
+#ifdef ENABLE_12p5_DMS_MODE
+ , encoder->frame_dms
+#endif
);
} else {
numResBits = 0;
@@ -203,31 +268,38 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s
/* Entropy encoding */
processEncoderEntropy_fl(bytes, &bp_side, &mask_side, h_EncSetup->targetBytes, encoder->BW_cutoff_bits,
BW_cutoff_idx, lastnz, encoder->yLen, lsbMode, quantizedGain, tns_numfilters, tns_order,
- h_EncSetup->ltpf_param, h_EncSetup->L_scf_idx, fac_ns_idx
- , bfi_ext, encoder->fs_idx
+ h_EncSetup->ltpf_param, h_EncSetup->L_scf_idx, fac_ns_idx,
+ bfi_ext, encoder->fs_idx
+#ifdef CR9_C_ADD_1p25MS
+#ifdef FIX_TX_RX_STRUCT_STEREO
+ , encoder->frame_dms, &h_EncSetup->Tx_ltpf
+#else
+ , encoder->frame_dms, &encoder->Tx_ltpf
+#endif
+#endif
);
/* Artithmetic encoding */
processAriEncoder_fl(bytes, bp_side, mask_side, q_d, tns_order, tns_numfilters, indexes, lastnz,
- h_EncSetup->codingdata,
+ h_EncSetup->codingdata,
h_EncSetup->resBits, numResBits, lsbMode, h_EncSetup->targetBitsAri,
h_EncSetup->enable_lpc_weighting);
-
+
if (encoder->combined_channel_coding == 0 && h_EncSetup->n_pc > 0)
{
LC3_INT32 xbuf[MAX_LEN] = {0}, nf_seed, tns_idx[M], zero_frame, nbits_residual, residualPresent, b_left, spec_inv_idx;
-
+
memset(h_EncSetup->resBits, 0, sizeof(*(h_EncSetup->resBits)) * MAX_RESBITS_LEN);
-
+
processAriDecoder_fl(bytes, bp_side, mask_side, encoder->yLen, encoder->fs_idx, h_EncSetup->enable_lpc_weighting,
tns_numfilters, lsbMode, lastnz, &bfi_ext, tns_order, fac_ns_idx, quantizedGain,
h_EncSetup->resBits, xbuf, &nf_seed, tns_idx, &zero_frame, h_EncSetup->targetBytes, &nbits_residual,
&residualPresent, encoder->frame_dms, h_EncSetup->n_pc, 0, h_EncSetup->total_bits >> 3, 1, &b_left,
&spec_inv_idx, encoder->hrmode);
-
+
processReorderBitstream_fl(bytes, h_EncSetup->n_pccw, h_EncSetup->n_pc, b_left, h_EncSetup->targetBytes);
}
-
+
}
int Enc_LC3PLUS_fl(LC3PLUS_Enc* encoder, void** input, uint8_t* output, int bps
@@ -239,7 +311,7 @@ int Enc_LC3PLUS_fl(LC3PLUS_Enc* encoder, void** input, uint8_t* output, int bps
LC3_INT32 totalBytes;
LC3_INT32 output_size2, input_size;
-
+
totalBytes = encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in);
for (ch = 0; ch < encoder->channels; ch++)
@@ -269,6 +341,6 @@ int Enc_LC3PLUS_fl(LC3PLUS_Enc* encoder, void** input, uint8_t* output, int bps
fec_encoder(encoder->epmode, encoder->epmr, output, input_size, output_size, encoder->channel_setup[0]->n_pccw);
}
-
+
return output_size;
}
diff --git a/lib_lc3plus/estimate_global_gain.c b/lib_lc3plus/estimate_global_gain.c
index c32d85c363016cb28552f0f71f101e81728add55..956402e73360c10ef314846533eebcd462aad269 100644
--- a/lib_lc3plus/estimate_global_gain.c
+++ b/lib_lc3plus/estimate_global_gain.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -15,7 +15,7 @@
void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC3_FLOAT* gain, LC3_INT* quantizedGain,
LC3_INT* quantizedGainMin, LC3_INT quantizedGainOff, LC3_FLOAT* targetBitsOff,
LC3_INT* old_targetBits, LC3_INT old_specBits
- , LC3_INT hrmode , LC3_INT regBits, LC3_FLOAT frame_ms
+ , LC3_INT hrmode , LC3_INT regBits, LC3PLUS_FrameDuration frame_ms
)
{
@@ -23,7 +23,47 @@ void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC
LC3_FLOAT g_min, x_max, tmp, ind, ind_min, target, ener;
LC3_FLOAT en[MAX_LEN / 4];
LC3_FLOAT reg_val = 4.656612873077393e-10;
+#ifdef FIX_1p25_GG_EST_TUPLES
+ LC3_INT tuples[1 + 4] = { -1, GG_1p25_WB_TUPLES, GG_1p25_SSWB_TUPLES, GG_1p25_SWB_TUPLES, GG_1p25_FB_TUPLES };
+ LC3_INT bw_idx;
+#endif
+#ifdef FIX_1p25_GG_EST_TUPLES
+ LC3_INT32 lg_extra;
+ if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ assert((MAX_LEN) >= ((lg / GG_1p25_MAX_TUPLES) + 1)*GG_1p25_MAX_TUPLES); /* en size check, for 1p25ms max tuple size*/
+ }
+#else
+#ifdef FIX_BOTH_1p25_TEST_NEW_GG_EST2
+ assert( (MAX_LEN / 4) >= ((8*4 + 2) / 2)); /* en size check, for 1p25ms SSWB */
+#endif
+#endif
+
+#ifdef FIX_1p25_GG_EST_TUPLES
+ lg_extra = 0;
+ bw_idx = MIN((lg / 10) - 1, 4);
+
+ if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ lg_extra = tuples[bw_idx] * (( lg + (tuples[bw_idx] - 1)) / tuples[bw_idx]) - lg;
+ /*x buffer is assert checked in enc_lc3_fl.c() for 1.25ms energy calculation */
+ for (i = lg; i < (lg + lg_extra); i++)
+ {
+ x[i] = 0.0; /* zero extended tail if a truncated tuple-block exists */
+ }
+ }
+#else
+#ifdef FIX_FLOAT_ENC_QUANTIZE_1P25MS_512KBPS
+ LC3_INT32 lg_extra;
+
+ lg_extra = lg - 4 * (lg / 4);
+ for ( i=lg; i< (lg+lg_extra); i++)
+ {
+ x[i] = 0.0; /* zero tail if a truncated quadruple exists */
+ }
+#endif
+#endif
if (*old_targetBits < 0) {
*targetBitsOff = 0;
} else {
@@ -39,7 +79,7 @@ void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC
if (hrmode && regBits > 0)
{
LC3_FLOAT M0 = 1e-5, M1 = 1e-5, rB_offset;
- LC3_FLOAT thresh = 2*frame_ms;
+ LC3_FLOAT thresh = 2*frame_ms*1.25;
for (i = 0; i < lg; i++)
{
M0 += fabs(x[i]);
@@ -55,75 +95,338 @@ void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC
ind_min = quantizedGainOff;
ind = 0;
*old_targetBits = -1;
- } else {
+ }
+ else {
if (hrmode == 1) {
g_min = x_max / (32768 * 256 - 2);
- } else {
+ }
+ else {
g_min = x_max / (32767 - 0.375);
}
/* Prevent positive rounding errors from LC3_LOG10 function */
ind_min = 28.0 * LC3_LOGTEN(g_min);
ind_min = ceil(ind_min + LC3_FABS(ind_min) * LC3_EPS);
-
+
assert(LC3_POW(10, ind_min / 28.0) >= g_min);
assert(ind_min <= (255 + quantizedGainOff));
+#ifdef FIX_FLOAT_ENC_QUANTIZE_1P25MS_512KBPS
+ N = lg + lg_extra;
+#else
N = lg;
+#endif
- j = 0;
- for (i = 0; i < N; i = i + 4) {
- tmp = x[i] * x[i];
- tmp += x[i + 1] * x[i + 1];
- tmp += x[i + 2] * x[i + 2];
- tmp += x[i + 3] * x[i + 3];
- en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOGTEN(tmp + reg_val));
- j++;
- }
- target = (28.0 / 20.0) * (1.4) * nbitsSQ;
- fac = 256;
- offset = 255 + quantizedGainOff;
-
- for (i = 0; i < 8; i++)
+#ifndef FIX_1p25_GG_EST_TUPLES
+#ifdef FIX_BOTH_1p25_TEST_NEW_GG_EST2
+ /* increase to at least 10 analysis bands for WB, SSWB 1p25ms */
+ if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS && lg <= 30)
{
- fac = fac >> 1;
- offset = offset - fac;
- ener = 0;
- iszero = 1;
+ j = 0;
+ for (i = 0; i < N; i = i + 2) /* steps of 2 for 1.25ms frame lengths */
+ {
+ tmp = x[i] * x[i];
+ tmp += x[i + 1] * x[i + 1];
+ en[j] = (28.0 / 20.0) * (7 * 0.5 + 10.0 * LC3_LOGTEN(tmp + reg_val)); /* offset of 7 per 4 coeff band now changed to 3.5 per 2 coeff band */
+ j++;
+ }
- for (j = N / 4 - 1; j >= 0; j--) {
- tmp = en[j] - offset;
+ target = (28.0 / 20.0) * (1.4) * nbitsSQ; /* global index domain sum over all 10 bands */
- if (tmp < (7.0) * (28.0 / 20.0)) {
- if (iszero == 0) {
- ener = ener + (2.7) * (28.0 / 20.0);
+ fac = 256;
+ offset = 255 + quantizedGainOff;
+
+ for (i = 0; i < 8; i++)
+ {
+ fac = fac >> 1;
+ offset = offset - fac;
+ ener = 0;
+ iszero = 1;
+
+ /* we sum up energy from the top, to not add up noisefilled coeffs */
+ for (j = N / 2 - 1; j >= 0; j--)
+ {
+ tmp = en[j] - offset;
+
+ if (tmp < ((7.0) * (28.0 / 20.0) * 0.5))
+ {
+ if (iszero == 0)
+ {
+ ener = ener + ((2.7) * (28.0 / 20.0)* 0.5); /* low cost in coded band zero */
+ }
}
- } else {
- if (tmp > (50.0) * (28.0 / 20.0)) {
- ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0);
- } else {
- ener = ener + tmp;
+ else
+ {
+ if (tmp > ((50.0) * (28.0 / 20.0)*0.5))
+ {
+ /* high value with many escapes */
+
+ ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0)*0.5;
+
+ }
+ else
+ {
+ ener = ener + (tmp*1.0);
+ }
+ iszero = 0;
}
+ } /* loop over over band N/2-1 ... 0 */
- iszero = 0;
+ if (ener > target && iszero == 0)
+ {
+ offset = offset + fac;
}
- }
- if (ener > target && iszero == 0) {
- offset = offset + fac;
+ } /* over 8 splits/iterations to handle all 256 possible shifts */
+
+ if (offset < ind_min)
+ {
+ *old_targetBits = -1;
}
- }
- if (offset < ind_min) {
- *old_targetBits = -1;
+ ind = MAX(ind_min, offset) - quantizedGainOff;
}
+ else
+#endif
+#endif
+
+
+
+#ifdef FIX_1p25_GG_EST_TUPLES
+
+#if GG_1p25_MAX_TUPLES == 2
+ /* the tuple/2-block with halved limits, is here separated from the 4-block loop ,
+ optionally they can be parametrized into one function */
+ if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+#else
+ if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS && tuples[bw_idx] == 2)
+#endif
+ {
+ assert(((lg / 2) * 2) == lg);
+
+ j = 0;
+ for (i = 0; i < N; i = i + 2)
+ {
+ tmp = x[i] * x[i];
+ tmp += x[i + 1] * x[i + 1];
+ en[j] = (28.0 / 20.0) * (7 * 0.5 + 10.0 * LC3_LOGTEN(tmp + reg_val)); /* offset of 7 per 4 coeff band now changed to 3.5 per 2 coeff band */
+ j++;
+ }
+
+ target = (28.0 / 20.0) * (1.4) * nbitsSQ; /* global index domain sum over all bands */
+
+ fac = 256;
+ offset = 255 + quantizedGainOff;
+
+ for (i = 0; i < 8; i++)
+ {
+ fac = fac >> 1;
+ offset = offset - fac;
+ ener = 0;
+ iszero = 1;
+
+ /* we sum up energy from the top, to not add up noisefilled coeffs */
+ for (j = N / 2 - 1; j >= 0; j--)
+ {
+ tmp = en[j] - offset;
- ind = MAX(ind_min, offset) - quantizedGainOff;
+ if (tmp < ((7.0) * (28.0 / 20.0) * 0.5))
+ {
+ if (iszero == 0)
+ {
+ ener = ener + ((2.7) * (28.0 / 20.0)* 0.5); /* low cost in coded band zero */
+ }
+ }
+ else
+ {
+ if (tmp > ((50.0) * (28.0 / 20.0)*0.5))
+ {
+ /* high value with many escapes */
+
+ ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0)*0.5;
+
+ }
+ else
+ {
+ ener = ener + (tmp*1.0);
+ }
+ iszero = 0;
+ }
+ } /* loop over over band N/2-1 ... 0 */
+
+ if (ener > target && iszero == 0)
+ {
+ offset = offset + fac;
+ }
+
+ } /* over 8 splits/iterations to handle all 256 possible shifts */
+
+ if (offset < ind_min)
+ {
+ *old_targetBits = -1;
+ }
+
+ ind = MAX(ind_min, offset) - quantizedGainOff;
+ }
+ else
+
+#if GG_1p25_MAX_TUPLES == 3
+ /* the 3tuple -block with modified limits, is here separated from the quadruple/4-block loop ,
+ optionally they can be parametrized into one function */
+ if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+#else
+
+ if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS && tuples[bw_idx] == 3)
+#endif
+ { /* 3 tuple loop */
+ N = 3 * (int)ceil(lg / 3.0);
+
+ assert(lg == 50 || lg == 40 || lg == 30 || lg == 20);
+ assert(N == (17 * 3) || N == (14 * 3) || N == (10 * 3) || N == (7 * 3));
+
+ j = 0;
+ for (i = 0; i < N; i = i + 3)
+ {
+ tmp = x[i] * x[i];
+ tmp += x[i + 1] * x[i + 1];
+ tmp += x[i + 2] * x[i + 2];
+ en[j] = (28.0 / 20.0) * (7 * 0.75 + 10.0 * LC3_LOGTEN(tmp + reg_val)); /* offset of 7*0.75 per 3 coeff band n */
+ j++;
+ }
+
+ target = (28.0 / 20.0) * (1.4) * nbitsSQ; /* global index domain sum over all bands */
+
+ fac = 256;
+ offset = 255 + quantizedGainOff;
+
+ for (i = 0; i < 8; i++)
+ {
+ fac = fac >> 1;
+ offset = offset - fac;
+ ener = 0;
+ iszero = 1;
+
+ /* we sum up energy from the top, to not add up noisefilled coeffs */
+ for (j = N / 3 - 1; j >= 0; j--)
+ {
+ tmp = en[j] - offset;
+
+ if (tmp < ((7.0) * (28.0 / 20.0) * 0.75))
+ {
+ if (iszero == 0)
+ {
+ ener = ener + ((2.7) * (28.0 / 20.0)* 0.75); /* low cost in coded band zero */
+ }
+ }
+ else
+ {
+ if (tmp > ((50.0) * (28.0 / 20.0)*0.75))
+ {
+ /* high value with many escapes */
+
+ ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0)*0.75;
+
+ }
+ else
+ {
+ ener = ener + (tmp*1.0);
+ }
+ iszero = 0;
+ }
+ } /* loop over over band N/3-1 ... 0 */
+
+ if (ener > target && iszero == 0)
+ {
+ offset = offset + fac;
+ }
+
+ } /* over 8 splits/iterations to handle all 256 possible shifts */
+
+ if (offset < ind_min)
+ {
+ *old_targetBits = -1;
+ }
+
+ ind = MAX(ind_min, offset) - quantizedGainOff;
+ }
+ else
+
+#endif /* end 2, 3 tuple loops */
+
+#ifdef FIX_1p25_GG_EST_TUPLES
+ { /* brackets for 4 tuple loop */
+ assert((((lg + lg_extra) / 4) * 4) == (lg + lg_extra));
+#endif
+#ifndef FIX_1p25_GG_EST_TUPLES
+#ifdef FIX_BOTH_1p25_TEST_NEW_GG_EST2
+ {
+#endif
+#endif
+
+ j = 0;
+ for (i = 0; i < N; i = i + 4) {
+ tmp = x[i] * x[i];
+ tmp += x[i + 1] * x[i + 1];
+ tmp += x[i + 2] * x[i + 2];
+ tmp += x[i + 3] * x[i + 3];
+ en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOGTEN(tmp + reg_val));
+ j++;
+ }
+
+ target = (28.0 / 20.0) * (1.4) * nbitsSQ;
+ fac = 256;
+ offset = 255 + quantizedGainOff;
+
+ for (i = 0; i < 8; i++)
+ {
+ fac = fac >> 1;
+ offset = offset - fac;
+ ener = 0;
+ iszero = 1;
+
+ for (j = N / 4 - 1; j >= 0; j--) {
+ tmp = en[j] - offset;
+
+ if (tmp < (7.0) * (28.0 / 20.0)) {
+ if (iszero == 0) {
+ ener = ener + (2.7) * (28.0 / 20.0);
+ }
+ }
+ else {
+ if (tmp > (50.0) * (28.0 / 20.0)) {
+ ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0);
+ }
+ else {
+ ener = ener + tmp;
+ }
+
+ iszero = 0;
+ }
+ }
+
+ if (ener > target && iszero == 0) {
+ offset = offset + fac;
+ }
+ }
+
+ if (offset < ind_min) {
+ *old_targetBits = -1;
+ }
+
+ ind = MAX(ind_min, offset) - quantizedGainOff;
+ }
+#ifdef FIX_1p25_GG_EST_TUPLES
+ }
+ /* end bracket for 4 tuple loop */
+#else
+#ifdef FIX_BOTH_1p25_TEST_NEW_GG_EST2
}
+#endif
+#endif
*quantizedGainMin = ind_min;
- *quantizedGain = ind;
+ *quantizedGain = ind;
*gain = LC3_POW(10.0, ((ind + quantizedGainOff) / 28.0));
}
diff --git a/lib_lc3plus/fft/cfft.c b/lib_lc3plus/fft/cfft.c
index 6ec89eb2992142e6899c773ddd43f8d5a6464907..ae8e5813bbf695fdcda4324e3aba01cde6a8d1e5 100644
--- a/lib_lc3plus/fft/cfft.c
+++ b/lib_lc3plus/fft/cfft.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -129,7 +129,9 @@ static void scramble(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT n, LC3_INT s)
for (m = 1, j = 0; m < (n - 1); m++) {
{
for (k = n >> 1; (!((j ^= k) & k)); k >>= 1)
+ {
;
+ }
}
if (j > m) {
diff --git a/lib_lc3plus/fft/cfft.h b/lib_lc3plus/fft/cfft.h
index a67d66f057aec75a329745723c6814139e4829dc..5794d48ceae6bc00cbcb9ec5f22370f85e258213 100644
--- a/lib_lc3plus/fft/cfft.h
+++ b/lib_lc3plus/fft/cfft.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/fft_15_16.h b/lib_lc3plus/fft/fft_15_16.h
index ced87c6671b6f664a8fae68bcf8be9b70139da70..a338ae24a68b2087decc95b02c380e861bf18638 100644
--- a/lib_lc3plus/fft/fft_15_16.h
+++ b/lib_lc3plus/fft/fft_15_16.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/fft_240_480.h b/lib_lc3plus/fft/fft_240_480.h
index 40969ba48e88a749e56070a3612410d16cd5701f..92f67cb1e0da062c437fb61adb088630136ed929 100644
--- a/lib_lc3plus/fft/fft_240_480.h
+++ b/lib_lc3plus/fft/fft_240_480.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/fft_2_9.h b/lib_lc3plus/fft/fft_2_9.h
index 0166ad43d75abbbf681199818925b5e150fc01d0..6080729fa0dd25cd27fc1dfd0df5f7ea3f2c4783 100644
--- a/lib_lc3plus/fft/fft_2_9.h
+++ b/lib_lc3plus/fft/fft_2_9.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/fft_32.h b/lib_lc3plus/fft/fft_32.h
index 39cffc69775ca21ee2c2514ceb19932a2a01db2f..8523d4b4527c14d81542a924ed36db5bd1db6e2f 100644
--- a/lib_lc3plus/fft/fft_32.h
+++ b/lib_lc3plus/fft/fft_32.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/fft_384_768.h b/lib_lc3plus/fft/fft_384_768.h
index 404ef79492e9b1879da06eabb893b5d0c5d590ec..805fbdb70cafa548c8f52c83b45563283af27a15 100644
--- a/lib_lc3plus/fft/fft_384_768.h
+++ b/lib_lc3plus/fft/fft_384_768.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/fft_60_128.h b/lib_lc3plus/fft/fft_60_128.h
index e2b17450e7b6d69ce36edf5b14f7416d89e2f698..da8922a709393e1750888ff1f7923d261b77575e 100644
--- a/lib_lc3plus/fft/fft_60_128.h
+++ b/lib_lc3plus/fft/fft_60_128.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/fft_generic.h b/lib_lc3plus/fft/fft_generic.h
index 32030b5ca413f20dccf0b3811d68ce9b9c865d2a..b17860de28cb24fef940ff1fcd0fcdfad8731c69 100644
--- a/lib_lc3plus/fft/fft_generic.h
+++ b/lib_lc3plus/fft/fft_generic.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/iis_fft.c b/lib_lc3plus/fft/iis_fft.c
index 085e60635cf83bdd559028b5a636958cbb8b1a03..9ead28b4afff9bf5491a5598078726a823bfa5f2 100644
--- a/lib_lc3plus/fft/iis_fft.c
+++ b/lib_lc3plus/fft/iis_fft.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/iis_fft.h b/lib_lc3plus/fft/iis_fft.h
index d68b27d8911a5816fd78cb039f4ca9e063002f48..3be02950fc3bd792d2045eff904bc0cc77dde9c2 100644
--- a/lib_lc3plus/fft/iis_fft.h
+++ b/lib_lc3plus/fft/iis_fft.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/iisfft.c b/lib_lc3plus/fft/iisfft.c
index aaca87db9f07b92d05d33d03b2ae90612afd8ac1..2889c9ae25f07e8ea538f096eed4f388c1020481 100644
--- a/lib_lc3plus/fft/iisfft.c
+++ b/lib_lc3plus/fft/iisfft.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/fft/iisfft.h b/lib_lc3plus/fft/iisfft.h
index 4fe8f3abc3490ce2327ea8efc48ffab515746906..c8809a3123c7e713944858abb82e65a70afafac4 100644
--- a/lib_lc3plus/fft/iisfft.h
+++ b/lib_lc3plus/fft/iisfft.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -23,26 +23,14 @@
the restrict keyword only gives a improvelent if more than one pointers are
passed to a function. also note that the MSVC __restrict behaves differently
from c99, the restrict property is not transferred to aliases.
+*/
- alloca is a bit problematic because behavior is not defined in case of stack
- overflow. most probably the program will crash. it might be possible to catch
- those errors but it depends on compiler support. msvc has a safer _malloca
- but gcc has nothing similar. */
#if defined _MSC_VER || defined __INTEL_COMPILER
-#include
-#define ALLOCA(size) _alloca(size)
-#define restrict __restrict
-#define inline __inline
+ #define restrict __restrict
+ #define inline __inline
#elif defined __GNUC__ || defined __clang__
-#define ALLOCA(size) __builtin_alloca(size)
-#define restrict __restrict__
-#define inline __inline
-#elif defined __TI_COMPILER_VERSION__
-#include
-#define ALLOCA(size) (assert(0 && "ALLOCA is not present for your compiler"), NULL)
-#warn "no stack allocation for you compiler"
-#else
-#error "no stack allocation for your compiler"
+ #define restrict __restrict__
+ #define inline __inline
#endif
diff --git a/lib_lc3plus/functions.h b/lib_lc3plus/functions.h
index 46daa64bf3f3757f8f546a4c2d5c878a7924eb2b..d26c1ff04854d22285f50084d60320f007eac734 100644
--- a/lib_lc3plus/functions.h
+++ b/lib_lc3plus/functions.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -15,12 +15,36 @@
#include "clib.h"
#include "defines.h"
#include "float.h"
-#include "lc3.h"
-#include "setup_dec_lc3.h"
-#include "setup_enc_lc3.h"
+#include "lc3plus.h"
+#include "setup_dec_lc3plus.h"
+#include "setup_enc_lc3plus.h"
#include "structs.h"
#include "util.h"
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+LC3_INT16 snsQuantScfEncLR(LC3_FLOAT* env, LC3_INT32* L_index, LC3_FLOAT* envq, Dct2 dct2structSNS, LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx);
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+/* needed in both encoder and decoder */
+LC3_FLOAT snslr_remove_st1_DC_fQ11(LC3_FLOAT *scfq, LC3_INT32 len);
+void snslr_st1B_vector_dec(LC3_INT16 idx, const LC3_INT16* LFCB, const LC3_INT16 *HFCB, const LC3_INT16* seg_cnt_cum, const LC3_INT16* idx12b_cb, LC3_FLOAT *st1B_vector);
+void snslr_st1C_vector_dec(LC3_INT16 idx, const LC3_INT8* CBW8, LC3_INT16 scaleQ4, LC3_INT16 inv_scaleQ15, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT *st1C_vector);
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+LC3_INT32 MSEsearchGeneric(LC3_FLOAT *scf, const LC3_FLOAT *sns_CB, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT* min_mse);
+LC3_INT32 MSEsearchCbBIdxMap(const LC3_FLOAT *scf, const LC3_INT16 *LFCB, const LC3_INT16 *HFCB, const LC3_INT16 *seg_cnt_cum, const LC3_INT16* idx12b_cb, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT* min_mse);
+LC3_INT32 MSEsearchGenericScaledW8(LC3_FLOAT *scf, const LC3_INT8 *sns_CBW8, LC3_INT16 scaleQ4, LC3_INT16 inv_scaleQ15, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT* min_mse);
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+void snsQuantScfDecLR(LC3_INT32* sns_vq_idx, LC3_FLOAT* scf_q, LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx);
+#endif
+
+/* Common */
+LC3_INT16 getLastNzBits (LC3_INT16 N);
+
/* FFT */
#include "fft/iisfft.h"
@@ -48,7 +72,7 @@ void dct4_free(Dct4* dct);
void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output);
/* mdct.c */
-void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC3_INT hrmode);
+void mdct_init(Mdct* mdct, LC3_INT length, LC3PLUS_FrameDuration frame_dms, LC3_INT fs_idx, LC3_INT hrmode);
void mdct_free(Mdct* mdct);
void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct);
@@ -58,13 +82,22 @@ LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT
void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT numbytes, LC3_INT bw_cutoff_bits,
LC3_INT bw_cutoff_idx, LC3_INT lastnz, LC3_INT N, LC3_INT lsbMode, LC3_INT gg_idx, LC3_INT num_tns_filters,
- LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* scf_idx, LC3_INT fac_ns_idx
- , LC3_INT bfi_ext, LC3_INT fs_idx
+ LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* scf_idx, LC3_INT fac_ns_idx,
+ LC3_INT bfi_ext, LC3_INT fs_idx
+#ifdef CR9_C_ADD_1p25MS
+ , LC3PLUS_FrameDuration frame_dms, LC3_INT16* Tx_ltpf
+#endif
);
void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT N, LC3_INT fs_idx,
LC3_INT bw_cutoff_bits, LC3_INT* bfi, LC3_INT* gg_idx, LC3_INT* scf_idx, LC3_INT* fac_ns_idx,
LC3_INT* tns_numfilters, LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* bw_cutoff_idx, LC3_INT* lastnz,
- LC3_INT* lsbMode, LC3_INT frame_dms
+ LC3_INT* lsbMode, LC3PLUS_FrameDuration frame_dms
+#ifdef CR9_C_ADD_1p25MS
+ , LC3_INT32 rx_status[2], LC3_INT16* mem_continuation
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ , LC3_INT32 *ltpfinfo_frame_cntr /* set/reset here, but increased outside during/when bfi for the channel */
+#endif
+#endif
);
void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT nt, LC3_INT totalBits, LC3_INT* nbits, LC3_INT* nbits2, LC3_INT fs,
LC3_INT* lastnzout, LC3_INT* codingdata, LC3_INT* lsbMode, LC3_INT mode, LC3_INT target, LC3_INT hrmode);
@@ -72,46 +105,50 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT
void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC3_FLOAT* gain, LC3_INT* quantizedGain,
LC3_INT* quantizedGainMin, LC3_INT quantizedGainOff, LC3_FLOAT* targetBitsOff,
LC3_INT* old_targetBits, LC3_INT old_specBits, LC3_INT bq_mode
- , LC3_INT regBits, LC3_FLOAT frame_ms
+ , LC3_INT regBits, LC3PLUS_FrameDuration frame_ms
);
void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting,
LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx,
LC3_INT gg_idx, uint8_t* resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes,
- LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3_INT frame_dms,
+ LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3PLUS_FrameDuration frame_dms,
LC3_INT32 n_pc, LC3_INT32 be_bp_left, LC3_INT32 be_bp_right, LC3_INT32 enc, LC3_INT32 *b_left, LC3_INT32 *spec_inv_idx,
LC3_INT hrmode
);
void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT gains[], const LC3_INT bands_offset[], LC3_INT fdns_npts);
-void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t * resBits,
- LC3_INT* numResBits
- , LC3_INT hrmode
+void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t * resBits, LC3_INT* numResBits, LC3_INT hrmode
+#ifdef ENABLE_12p5_DMS_MODE
+ , LC3PLUS_FrameDuration frame_dms
+#endif
);
void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits
, LC3_INT hrmode
+#ifdef ENABLE_12p5_DMS_MODE
+ , LC3PLUS_FrameDuration frame_dms
+#endif
);
void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits,
LC3_INT* gainChange, LC3_INT fs_idx
- , LC3_INT16 hrmode, LC3_INT16 frame_dms
+ , LC3_INT16 hrmode, LC3PLUS_FrameDuration frame_dms
);
void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off);
-void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms,
+void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3PLUS_FrameDuration frame_dms,
LC3_INT target_bytes
);
-void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx);
+void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3PLUS_FrameDuration frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx);
void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0,
LC3_INT* pitch_flag,
- LC3_INT* T0_out,LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms);
+ LC3_INT* T0_out,LC3_FLOAT* normcorr_out, LC3_INT len, LC3PLUS_FrameDuration frame_dms);
-void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3_INT frame_dms, LC3_INT nBits,
+void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3PLUS_FrameDuration frame_dms, LC3_INT nBits,
LC3_INT* order_out, LC3_INT* rc_idx, LC3_INT* tns_numfilters, LC3_INT* bits_out
, LC3_INT16 near_nyquist_flag
);
@@ -119,36 +156,58 @@ void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLO
void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs);
-void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx);
+void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx
+#ifdef CR9_C_ADD_1p25MS
+ , LC3PLUS_FrameDuration frame_dms, LC3_FLOAT *LT_normcorr, LC3_FLOAT normcorr
+#endif
+);
void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_LC3_INT);
-void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx);
+void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3PLUS_FrameDuration frame_dms, LC3_INT* bw_idx);
void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index,
- const LC3_INT bands_number, const LC3_FLOAT* ener
- , const LC3_INT16 frame_dms, const LC3_INT16 hrmode );
-void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d);
+ const LC3_INT bands_number, const LC3_FLOAT* ener
+ , const LC3PLUS_FrameDuration frame_dms, const LC3_INT16 hrmode );
+void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3PLUS_FrameDuration frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d);
void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_INT winLen, LC3_INT last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x,
Dct4* dct);
void ProcessingITDA_WIN_OLA_fl(LC3_FLOAT* x_tda, LC3_INT32 yLen, const LC3_FLOAT* win, LC3_INT32 winLen, LC3_INT32 last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x);
-void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms,
+void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3PLUS_FrameDuration frame_dms,
LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch,
LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits
- , LC3_INT16 hrmode
+ , LC3_INT16 hrmode
+#ifdef CR9_C_ADD_1p25MS
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ ,LC3_INT16* Tx_ltpf
+#else
+ ,LC3_INT16 Tx_ltpf
+#endif
+#endif
);
+#ifdef CR9_C_ADD_1p25MS
+void processTdcZeroCleanup(LC3_FLOAT *energies, LC3_INT32 n_bands, LC3PLUS_FrameDuration frame_dms);
+#endif
+
void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y,
LC3_INT* mem_pitch_LC3_INT, LC3_INT* mem_pitch_fr, LC3_FLOAT* mem_gain, LC3_INT* mem_beta_idx, LC3_INT bfi,
- LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod, LC3_FLOAT damping
+ LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT *conf_beta, LC3_INT concealMethod, LC3_FLOAT damping
, LC3_INT *mem_ltpf_active
- , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3_INT frame_dms
+ , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3PLUS_FrameDuration frame_dms
+#ifdef CR9_C_ADD_1p25MS
+ , LC3_INT16* mem_continuation, LC3_INT32* mem_param_prev, LC3_INT16* mem_pitch_int_prev,
+ LC3_INT16* mem_pitch_fr_prev, LC3_INT32* mem_beta_idx_prev, LC3_FLOAT* mem_gain_prev,
+ LC3_INT16* pitch_stability_counter,
+ LC3_FLOAT* gain_step,
+ LC3_FLOAT conf_beta_max
+#endif
);
void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[],
- LC3_INT mem_out_len, LC3_FLOAT y[], LC3_INT* y_len, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT fs);
+ LC3_INT mem_out_len, LC3_FLOAT y[], LC3_INT* y_len, LC3_INT fs_idx, LC3PLUS_FrameDuration frame_dms, LC3_INT fs);
void write_bit_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT bit);
void write_uint_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT val, LC3_INT numbits);
@@ -187,6 +246,10 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, LC3_UINT8* input, int input_b
void* balloc(void* base, size_t* base_size, size_t size);
+#ifdef FIX_BOTH_1p25_WB_GLOBGAINOFFSET_NONBE
+LC3_INT16 calc_GGainOffset_1p25(LC3_INT16 total_bits, LC3_INT16 fs_idx);
+#endif
+
void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi,
PlcAdvSetup *PlcAdvSetup, PlcSetup *PlcSetup, LC3_INT plcMeth, LC3_INT ltpf_pitch_int, LC3_INT ltpf_pitch_fr,
LC3_INT tilt, const LC3_INT *bands_offset, LC3_INT bands_number, const LC3_INT *bands_offsetPLC,
@@ -213,13 +276,13 @@ LC3_INT32 fec_decoder(LC3_UINT8 *iobuf, LC3_INT16 slot_bytes, LC3_INT32 *data_by
LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len);
-void processPcClassify_fl(LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi);
+void processPcClassify_fl(LC3_INT32 pitch_present, LC3PLUS_FrameDuration frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi);
void processPcMain_fl(LC3_INT32 *bfi, LC3PLUS_Dec* decoder, LC3_FLOAT *sqQdec, DecSetup* h_DecSetup, LC3_INT32 pitch_present, LC3_FLOAT stab_fac, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 fac_ns_idx, pcState *statePC, LC3_INT32 spec_inv_idx, LC3_INT32 yLen);
void processPcUpdate_fl(LC3_INT32 bfi, LC3_FLOAT *q_res, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 rframe, LC3_INT32 *BW_cutoff_idx_nf, LC3_INT32 *prev_BW_cutoff_idx_nf, LC3_INT32 fac_ns_idx, LC3_FLOAT *prev_fac_ns, LC3_FLOAT *fac, LC3_FLOAT *q_old_res, LC3_FLOAT *prev_gg, LC3_INT32 spec_inv_idx, LC3_INT32 yLen);
void processPcApply_fl(LC3_FLOAT *q_res, LC3_FLOAT *q_old_res, LC3_FLOAT *q_d_prev, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_FLOAT *prev_gg, LC3_FLOAT *fac, LC3_INT32 *pc_nbLostCmpt);
void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *nbLostCmpt, LC3_INT32 bfi,
- LC3_FLOAT *xcorr, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 pitch_int,
+ LC3_FLOAT *xcorr, LC3_INT32 framelength, LC3PLUS_FrameDuration frame_dms, LC3_INT32 pitch_int,
LC3_INT32 fs, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 tilt, PlcAdvSetup *plcAd
, LC3_INT32 hrmode
);
@@ -229,20 +292,20 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed,
LC3_INT32 *pc_seed, LC3_INT32 ns_nbLostCmpt_pc,
LC3_INT32 ns_nbLostCmpt, LC3_FLOAT *stabFac, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast,
LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi,
- LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2,
+ LC3PLUS_FrameDuration frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2,
LC3_FLOAT *cum_fflcAtten
, LC3_UINT8 plc_fadeout_type
);
void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb,
- LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow,
+ LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3PLUS_FrameDuration frame_dms, LC3_FLOAT *cum_fading_slow,
LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx
, LC3_UINT8 plc_fadeout_type
);
void plc_phEcu_F0_refine_first(LC3_INT32 *plocs, LC3_INT32 n_plocs, LC3_FLOAT *f0est, const LC3_INT32 Xabs_len,
LC3_FLOAT *f0binPtr, LC3_FLOAT *f0gainPtr, const LC3_INT32 nSubm);
-void processTdcLpcEstimation_fl(LC3_FLOAT *r, LC3_INT32 fs_idx, LC3_INT32 len, LC3_FLOAT *A, LC3_INT32 frame_dms);
+void processTdcLpcEstimation_fl(LC3_FLOAT *r, LC3_INT32 fs_idx, LC3_INT32 len, LC3_FLOAT *A, LC3PLUS_FrameDuration frame_dms);
LC3_FLOAT plc_phEcuSetF0Hz(LC3_INT32 fs, LC3_FLOAT *old_pitchPtr);
@@ -314,14 +377,14 @@ void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT
void processTdcTdac_fl(const LC3_FLOAT *synth_inp, const LC3_FLOAT *win, LC3_INT32 frame_length, LC3_INT32 la_zeroes, LC3_FLOAT *ola_mem);
void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, LC3_INT32 lpc_order);
-void processTdcApply_fl(const LC3_INT32 pitch_LC3_INT, const LC3_FLOAT *preemphFac, const LC3_FLOAT* A, const LC3_INT32 lpc_order, const LC3_FLOAT* pcmbufHist, const LC3_INT32 max_len_pcm_plc, const LC3_INT32 N, const LC3_INT32 frame_dms,
+void processTdcApply_fl(const LC3_INT32 pitch_LC3_INT, const LC3_FLOAT *preemphFac, const LC3_FLOAT* A, const LC3_INT32 lpc_order, const LC3_FLOAT* pcmbufHist, const LC3_INT32 max_len_pcm_plc, const LC3_INT32 N, const LC3PLUS_FrameDuration frame_dms,
const LC3_INT32 SampRate, const LC3_INT32 nbLostCmpt, const LC3_INT32 overlap, const LC3_FLOAT *stabFac, LC3_FLOAT harmonicBuf[MAX_PITCH], LC3_FLOAT synthHist[M],
LC3_INT32* fract, LC3_INT16* seed, LC3_FLOAT* gain_c, LC3_FLOAT* alpha, LC3_FLOAT* synth
- ,LC3_UINT8 plc_fadeout_type
+ , LC3_UINT8 plc_fadeout_type
,LC3_FLOAT* alpha_type_2_table
);
void* balloc(void* base, size_t* base_size, size_t size);
-LC3_FLOAT type_2_fadeout(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms);
+LC3_FLOAT type_2_fadeout(LC3_INT32 nbLostFramesInRow, LC3PLUS_FrameDuration frame_dms);
#endif
diff --git a/lib_lc3plus/imdct.c b/lib_lc3plus/imdct.c
index b8fc4e7985b2199ce23b6c68c2c503b5ced4ceb0..b99ef8c206f05760d34fa510c1c7207ef8b9a05c 100644
--- a/lib_lc3plus/imdct.c
+++ b/lib_lc3plus/imdct.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/lc3.c b/lib_lc3plus/lc3plus.c
similarity index 88%
rename from lib_lc3plus/lc3.c
rename to lib_lc3plus/lc3plus.c
index b275ed8084fc1b1caa5cce48e6ef18db7fa1af86..c8a529021a9a18248bf85d8e7a2276d2a1d2261d 100644
--- a/lib_lc3plus/lc3.c
+++ b/lib_lc3plus/lc3plus.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -9,13 +9,13 @@
#include "options.h"
#include "wmc_auto.h"
-#include "lc3.h"
+#include "lc3plus.h"
#include "defines.h"
#include "functions.h"
#include
-#include "setup_dec_lc3.h"
-#include "setup_enc_lc3.h"
+#include "setup_dec_lc3plus.h"
+#include "setup_enc_lc3plus.h"
#define RETURN_IF(cond, error) \
if (cond) \
@@ -65,16 +65,21 @@ static int lc3plus_plc_mode_supported(LC3PLUS_PlcMode plc_mode)
return 0;
}
-static int lc3plus_frame_size_supported(float frame_ms)
+static int lc3plus_frame_size_supported(LC3PLUS_FrameDuration frame_dms)
{
- switch ((int)(ceil(frame_ms * 10)))
+ switch (frame_dms)
{
- case 25: /* fallthru */
- case 50: /* fallthru */
- case 75: /* fallthru */
- case 100: return 1;
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS: /* fallthru */
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS: /* fallthru */
+ case LC3PLUS_FRAME_DURATION_5MS: /* fallthru */
+ case LC3PLUS_FRAME_DURATION_7p5MS: /* fallthru */
+ case LC3PLUS_FRAME_DURATION_10MS:
+ return 1;
default: break;
}
+
return 0;
}
@@ -151,6 +156,9 @@ int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder)
{
int ch = 0, totalBytes = 0;
int bitrate;
+#ifdef CR9_C_ADD_1p25MS
+ int frame_ns;
+#endif
RETURN_IF(encoder == NULL, 0);
RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR);
@@ -158,9 +166,12 @@ int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder)
{
totalBytes += encoder->channel_setup[ch]->targetBytes;
}
-
+#ifdef CR9_C_ADD_1p25MS
+ frame_ns = (int)(1250L * encoder->frame_dms);
+ bitrate = (int) ((totalBytes*8L) * 1000000L + (frame_ns - 1) ) / (frame_ns);
+#else
bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms;
-
+#endif
if (encoder->fs_in == 44100)
{
int rem = bitrate % 480;
@@ -187,13 +198,18 @@ int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder)
return encoder->frame_length - 2 * encoder->la_zeroes;
}
-LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_dms)
+LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, LC3PLUS_FrameDuration frame_dms)
{
RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR);
- RETURN_IF(!lc3plus_frame_size_supported(frame_dms / 10.0), LC3PLUS_FRAMEMS_ERROR);
+ RETURN_IF(!lc3plus_frame_size_supported(frame_dms), LC3PLUS_FRAMEMS_ERROR);
RETURN_IF(encoder->lc3_br_set, LC3PLUS_BITRATE_SET_ERROR);
+#ifdef CR9_C_ADD_1p25MS
+ RETURN_IF(encoder->fs == 8000 && frame_dms == LC3PLUS_FRAME_DURATION_1p25MS, LC3PLUS_SAMPLERATE_ERROR);
+#endif
+
encoder->frame_dms = frame_dms;
- encoder->frame_ms = frame_dms / 10.0;
+ encoder->frame_ms = frame_dms;
+
set_enc_frame_params(encoder);
return LC3PLUS_OK;
}
@@ -279,14 +295,18 @@ int lc3plus_dec_get_scratch_size(const LC3PLUS_Dec *decoder)
return 0;
}
-LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_dms)
+LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, LC3PLUS_FrameDuration frame_dms)
{
RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR);
- RETURN_IF(!lc3plus_frame_size_supported(frame_dms / 10.0), LC3PLUS_FRAMEMS_ERROR);
- RETURN_IF(decoder->plcMeth == 2 && frame_dms != 100, LC3PLUS_FRAMEMS_ERROR);
-
+ RETURN_IF(!lc3plus_frame_size_supported(frame_dms), LC3PLUS_FRAMEMS_ERROR);
+ RETURN_IF(decoder->plcMeth == 2 && frame_dms != LC3PLUS_FRAME_DURATION_10MS, LC3PLUS_FRAMEMS_ERROR);
+#ifdef CR9_C_ADD_1p25MS
+ RETURN_IF(decoder->fs == 8000 && frame_dms == LC3PLUS_FRAME_DURATION_1p25MS, LC3PLUS_SAMPLERATE_ERROR);
+#endif
+
decoder->frame_dms = frame_dms;
- decoder->frame_ms = frame_dms / 10.0;
+ decoder->frame_ms = frame_dms;
+
set_dec_frame_params(decoder);
return LC3PLUS_OK;
}
@@ -403,7 +423,7 @@ LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmod
error = encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK;
if (error != LC3PLUS_OK)
{
- encoder->epmode = oldEpmode; // preserve old epmode in case of failure
+ encoder->epmode = oldEpmode; /* preserve old epmode in case of failure */
}
return error;
}
diff --git a/lib_lc3plus/lc3.h b/lib_lc3plus/lc3plus.h
similarity index 96%
rename from lib_lc3plus/lc3.h
rename to lib_lc3plus/lc3plus.h
index b5f8809e7e167302c30da51e2989743d09fd21fe..955e22fe78a70c5b79259a176a38621b0fa266d3 100644
--- a/lib_lc3plus/lc3.h
+++ b/lib_lc3plus/lc3plus.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -7,7 +7,7 @@
* estoppel or otherwise. *
******************************************************************************/
-/*! \file lc3.h
+/*! \file lc3plus.h
* This header provides the API for LC3plus.
*
* This library is targeting devices with extreme memory limitations, so memory management
@@ -23,9 +23,11 @@
#ifndef LC3PLUS_H
#define LC3PLUS_H
-#ifndef _MSC_VER
#include "options.h"
#include "wmc_auto.h"
+#include "defines.h" /* Required for CR9_C_ADD_1p25MS */
+
+#ifndef _MSC_VER
#include
#else
typedef unsigned char uint8_t;
@@ -37,7 +39,7 @@ typedef __int32 int32_t;
#define LC3PLUS_VERSION_INT(major, minor, micro) (((major) << 16) | ((minor) << 8) | (micro))
/*! Version number to ensure header and binary are matching. */
-#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 7, 4)
+#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 8, 0)
/*! Maximum number of supported channels. The actual binary might support
* less, use lc3plus_channels_supported() to check. */
@@ -57,6 +59,20 @@ typedef __int32 int32_t;
#define LC3PLUS_DEC_MAX_SIZE 87528
/*! Error codes returned by functions. */
+
+typedef enum {
+ LC3PLUS_FRAME_DURATION_UNDEFINED = 0, /* Invalid */
+#ifdef CR9_C_ADD_1p25MS
+ LC3PLUS_FRAME_DURATION_1p25MS = 1, /* 1.25 ms */
+#endif
+ LC3PLUS_FRAME_DURATION_2p5MS = 2, /* 2.5 ms */
+ LC3PLUS_FRAME_DURATION_5MS = 4, /* 5 ms */
+ LC3PLUS_FRAME_DURATION_7p5MS = 6, /* 7.5 ms */
+ LC3PLUS_FRAME_DURATION_10MS = 8, /* 10 ms */
+} LC3PLUS_FrameDuration;
+
+
+
typedef enum
{
LC3PLUS_PLC_ADVANCED = 1 /*!< Enhanced concealment method */
@@ -286,7 +302,7 @@ int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder);
* \param[in] frame_ms Frame length in ms.
* \return LC3PLUS_OK on success or appropriate error code.
*/
-LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_ms);
+LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, LC3PLUS_FrameDuration frame_ms);
/*! Set encoder Low-frequency effect moded. deactivates LTPF, TNS, NF
@@ -448,7 +464,7 @@ int lc3plus_dec_get_delay(const LC3PLUS_Dec* decoder);
* \param[in] frame_ms Frame length in ms.
* \return LC3PLUS_OK on success or appropriate error code.
*/
-LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_ms);
+LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, LC3PLUS_FrameDuration frame_ms);
/*! Free memory allocated within LC3plus decoder struct.
diff --git a/lib_lc3plus/lc3plus_fft.c b/lib_lc3plus/lc3plus_fft.c
index 75f8787e25ffdfc7b76bd29060db07c467ae17d9..b2c6b66dd092fccd80b195b86ccb89fd496413fe 100644
--- a/lib_lc3plus/lc3plus_fft.c
+++ b/lib_lc3plus/lc3plus_fft.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -18,13 +18,13 @@ void fft_init(Fft* fft, int length)
{
HANDLE_IIS_FFT handle = NULL;
IIS_FFT_ERROR error = 0;
- assert(length % 2 == 0);
fft->length = length;
error = LC3_IIS_CFFT_Create(&handle, length, IIS_FFT_FWD);
assert(error == IIS_FFT_NO_ERROR);
+ (void) error;
fft->handle = handle;
}
@@ -38,6 +38,8 @@ void fft_free(Fft* fft)
assert(error == IIS_FFT_NO_ERROR);
memset(fft, 0, sizeof(*fft));
}
+
+ (void) error;
}
void real_fft_free(Fft* fft)
@@ -50,6 +52,8 @@ void real_fft_free(Fft* fft)
assert(error == IIS_FFT_NO_ERROR);
memset(fft, 0, sizeof(*fft));
}
+
+ (void) error;
}
void real_fft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle)
@@ -62,6 +66,8 @@ void real_fft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle)
error = LC3_IIS_RFFT_Create(handle, length, IIS_FFT_FWD);
assert(error == IIS_FFT_NO_ERROR);
fft->handle = *handle;
+
+ (void) error;
}
@@ -76,6 +82,8 @@ void real_ifft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle)
assert(error == IIS_FFT_NO_ERROR);
fft->handle = *handle;
+
+ (void) error;
}
void fft_apply(Fft* fft, const Complex* input, Complex* output)
@@ -84,6 +92,8 @@ void fft_apply(Fft* fft, const Complex* input, Complex* output)
error = LC3_IIS_FFT_Apply_CFFT(fft->handle, input, output);
assert(error == IIS_FFT_NO_ERROR);
+
+ (void) error;
}
@@ -96,5 +106,7 @@ void real_fft_apply(Fft* fft, const LC3_FLOAT* input, LC3_FLOAT* output)
error = LC3_IIS_FFT_Apply_RFFT(fft->handle, input, output);
assert(error == IIS_FFT_NO_ERROR);
+
+ (void) error;
}
diff --git a/lib_lc3plus/license.h b/lib_lc3plus/license.h
index 0ea743b404b1111761c7522591c007311b731b71..2c5e6ceae41ab717d471c666f76606161294ae28 100644
--- a/lib_lc3plus/license.h
+++ b/lib_lc3plus/license.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -13,7 +13,7 @@
static const char *const LICENSE =
"*******************************************************************************\n"
- "* ETSI TS 103 634 V1.5.1 *\n"
+ "* ETSI TS 103 634 V1.6.1 *\n"
"* Low Complexity Communication Codec Plus (LC3plus) *\n"
"* Floating Point Software V%i.%i.%iETSI, " __DATE__ " *\n"
"* Copyright licence is solely granted through ETSI Intellectual Property *\n"
diff --git a/lib_lc3plus/ltpf_coder.c b/lib_lc3plus/ltpf_coder.c
index 3457b6ba66bd36e54cc7c98796919e82e898dfb5..c4a8ee57648779e9db0845750dab85d7de1a346d 100644
--- a/lib_lc3plus/ltpf_coder.c
+++ b/lib_lc3plus/ltpf_coder.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -32,10 +32,17 @@ LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len)
return max_i;
}
-void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms,
+void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3PLUS_FrameDuration frame_dms,
LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch,
LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits
- , LC3_INT16 hrmode
+ , LC3_INT16 hrmode
+#ifdef CR9_C_ADD_1p25MS
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ ,LC3_INT16* Tx_ltpf
+#else
+ ,LC3_INT16 Tx_ltpf
+#endif
+#endif
)
{
LC3_FLOAT buffer[LTPF_MEMIN_LEN + LEN_12K8 + 1 + (LEN_12K8 >> 2)], sum = 0, cor_up[(MAX_PITCH_12K8 - MIN_PITCH_12K8) / 2] = {0}, *x;
@@ -45,8 +52,13 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
delta_up = 0, delta_down = 0, pitch_index = 0, gain = 0, acflen = 0;
LC3_FLOAT cor_tmp, cor_int_tmp, norm_corr = 0, cor[MAX_LEN_NR], cor_int[MAX_LEN_NR], sum1 = 0, sum2 = 0, sum3 = 0;
LC3_FLOAT pitch = 0;
+ LC3_FLOAT normCorrTh = 0.0f;
+#if defined (CR9_C_ADD_1p25MS)
+ LC3_INT16 activation_due_to_past_corr, activation_due_to_stable_pitch, activation;
+#endif
+
+ UNUSED(mem_norm_corr_past_past);
- LC3_FLOAT normCorrTh = 0.0f;
if (hrmode) {
normCorrTh = 0.4;
} else {
@@ -55,11 +67,28 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
/* Signal Buffer */
N = xLen - 1;
+ acflen = N;
+
+ if (frame_dms == LC3PLUS_FRAME_DURATION_5MS)
+ {
+ acflen = 2 * N;
+ }
+ if (frame_dms == LC3PLUS_FRAME_DURATION_2p5MS)
+ {
+ acflen = 4 * N;
+ }
+#ifdef CR9_C_ADD_1p25MS
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ acflen = 8 * N;
+ }
+#endif
+
x = &buffer[memLen];
- move_float(buffer, mem_old_x, memLen);
- move_float(x, xin, xLen);
- move_float(mem_old_x, &buffer[N], xLen + memLen - N);
+ move_float( buffer, mem_old_x, memLen );
+ move_float( x, xin, xLen );
+ move_float( mem_old_x, &buffer[N], xLen + memLen - N );
ltpf_active = 0;
norm_corr = 0;
@@ -74,17 +103,29 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
t0_max = pitch_ol + pitch_search_delta;
t0_min = MAX(t0_min, MIN_PITCH_12K8);
t0_max = MIN(t0_max, MAX_PITCH_12K8);
+
+ /* Cross-Correlation Bounds */
+ t_min = t0_min - pitch_search_L_interpol1;
+ t_max = t0_max + pitch_search_L_interpol1;
+
+#ifndef FIX_LTPF_PITCH_MEM_LEN
acflen = N;
-
- if (frame_dms == 25)
+
+ if ( frame_dms == LC3PLUS_FRAME_DURATION_2p5MS )
{
acflen = 2 * N;
x = x - N;
}
-
- /* Cross-Correlation Bounds */
- t_min = t0_min - pitch_search_L_interpol1;
- t_max = t0_max + pitch_search_L_interpol1;
+#ifdef CR9_C_ADD_1p25MS
+ if ( frame_dms == LC3PLUS_FRAME_DURATION_1p25MS )
+ {
+ acflen = 4 * N;
+ x = x - 80;
+ }
+#endif
+#else
+ x = x - (memLen - LTPF_MEMIN_LEN);
+#endif
/* Compute norm */
sum1 = sum2 = 0;
@@ -92,13 +133,13 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
sum1 += x[j] * x[j];
sum2 += x[j - t_min] * x[j - t_min];
}
-
+
/* Do first iteration outside of loop */
sum = mac_loop(x, &x[-t_min], acflen);
sum3 = LC3_SQRT(sum1 * sum2) + 1.00e-05;
norm_corr = sum / sum3;
-
+
norm_corr = MAX(0, norm_corr);
cor[0] = norm_corr;
@@ -111,7 +152,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
sum3 = LC3_SQRT(sum1 * sum2) + 1.00e-05;
norm_corr = sum / sum3;
-
+
norm_corr = MAX(0, norm_corr);
cor[i - t_min] = norm_corr;
@@ -129,7 +170,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
pitch_fr = 0;
} else {
j = 0;
-
+
for (i = 0; i < pitch_search_upsamp * (t_max - t_min) + 1; i = i + pitch_search_upsamp) {
cor_up[i] = cor[j];
j++;
@@ -155,7 +196,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
} else {
delta_down = pitch_search_upsamp - step;
}
-
+
j = 0;
for (i = midpoint - delta_down - 1; i <= midpoint + delta_up; i = i + step) {
cor[j] = cor_int[i];
@@ -178,7 +219,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
(pitch_int < RES2_PITCH_12K8 && pitch_int >= RES4_PITCH_12K8 && (pitch_fr == 0 || pitch_fr == 2)) ||
(pitch_int < RES4_PITCH_12K8 && pitch_int >= MIN_PITCH_12K8 &&
(pitch_fr == 0 || pitch_fr == 1 || pitch_fr == 2 || pitch_fr == 3)));
-
+
if (pitch_int < RES4_PITCH_12K8) {
pitch_index = pitch_int * 4 + pitch_fr - (MIN_PITCH_12K8 * 4);
} else if (pitch_int < RES2_PITCH_12K8) {
@@ -189,7 +230,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
assert(pitch_index >= 0 && pitch_index < 512);
pitch = (LC3_FLOAT) pitch_int + (LC3_FLOAT) pitch_fr / 4.0;
-
+
/* Normalized Correlation */
sum1 = sum2 = sum3 = 0;
@@ -203,7 +244,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
x[n - pitch_int] * enc_inter_filter[pitch_fr][1] +
x[n - pitch_int - 1] * enc_inter_filter[pitch_fr][2] +
x[n - pitch_int - 2] * enc_inter_filter[pitch_fr][3];
-
+
sum1 += cor_tmp * cor_int_tmp;
sum2 += cor_tmp * cor_tmp;
sum3 += cor_int_tmp * cor_int_tmp;
@@ -218,19 +259,42 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
norm_corr = 0;
}
- if (ltpf_enable == 1) {
+ if (ltpf_enable == 1)
+ {
/* Decision if ltpf active */
- if ((*mem_on == 0 && (frame_dms == 100 || *mem_norm_corr_past_past > 0.94) && *mem_norm_corr_past > 0.94 &&
+#if defined (CR9_C_ADD_1p25MS)
+ activation_due_to_past_corr = mem_norm_corr_past[1] > 0.94;
+ activation_due_to_stable_pitch = 1;
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ activation_due_to_past_corr &= (mem_norm_corr_past[2] > 0.94);
+ activation_due_to_past_corr &= (mem_norm_corr_past[3] > 0.94);
+ activation_due_to_past_corr &= (mem_norm_corr_past[4] > 0.94);
+
+ activation_due_to_stable_pitch = LC3_FMAX(pitch, *mem_pitch) * 0.7f < LC3_FMIN(pitch, *mem_pitch);
+ }
+ activation = activation_due_to_past_corr && activation_due_to_stable_pitch;
+ if ((*mem_on == 0 && (frame_dms == LC3PLUS_FRAME_DURATION_10MS || activation) && mem_norm_corr_past[0] > 0.94 &&
+ norm_corr > 0.94) ||
+ ((*mem_on == 1 && norm_corr > 0.9) && activation_due_to_stable_pitch) ||
+ (*mem_on == 1 && LC3_FABS(pitch - *mem_pitch) < 2 && (norm_corr - mem_norm_corr_past[0]) > -0.1 &&
+ norm_corr > 0.84))
+ {
+ ltpf_active = 1;
+ }
+#else
+ if ((*mem_on == 0 && (frame_dms == LC3PLUS_FRAME_DURATION_10MS || *mem_norm_corr_past_past > 0.94) && *mem_norm_corr_past > 0.94 &&
norm_corr > 0.94) ||
(*mem_on == 1 && norm_corr > 0.9) ||
(*mem_on == 1 && LC3_FABS(pitch - *mem_pitch) < 2 && (norm_corr - *mem_norm_corr_past) > -0.1 &&
- norm_corr > 0.84)) {
+ norm_corr > 0.84))
+ {
ltpf_active = 1;
}
+#endif
}
gain = 4;
-
} else {
gain = 0;
norm_corr = pitch_ol_norm_corr;
@@ -248,8 +312,60 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC
*bits = 1;
}
- if (frame_dms < 100) {
+
+#ifdef CR9_C_ADD_1p25MS
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ LC3_INT32 tmp = MIN(*Tx_ltpf, 1); /* 0 == phaseA, 1==PhaseB ) */
+ /* tmp [0 or 1} will points to 2 ltp bits in any case */
+ if ( param[0] == 0 && tmp != 0 )
+ {
+ /* pitch correlation dropped from high(ltp active || ltpf_active) to low (no ltp info at all ),
+ we select to NOT transmit the remaining phaseB lag info for potential use in a next possible PLC frame */
+ *Tx_ltpf = 0; /* kill the lag transmission state from the encoder side */
+ /* tmp stays 0 or 1 */
+ }
+
+ /* 00 (ltp=0, ltpf=0, no Phase 2b),
+ 010 (ltp=1, ltpf=0, phaseA, 7b),
+ 011 (ltp=1, ltpf=0, phaseB , 7b), lowered lag res for PLC
+ 10x (ltp=1, ltpf=1) phaseA 6b)
+ 11x (ltp=1, ltpf=1) phaseB 7b)
+ */
+
+ if (param[0] != 0)
+ {
+ if (param[1] == 0)
+ { /* ltp active, PLC usage case LTPF inactive 01[PhaseA]=010=2, or 01[phaseB]=011=3
+ path ltp active and ltpf inactive */
+ tmp = (0x02 | tmp); /* phase Info in LSB b0, LTPFactive in b1, tmp becomes 2 or 3 */
+ }
+ else
+ { /*param[1] != 0*/ /* ltp active, ltpf active */
+ assert(param[2] >= 0 && param[2] <= 511);
+ tmp = (0x04 | (tmp << 1)); /* LTPF in b2, phase b1, always zero in b0 , tmp becomes 4 or 6 */
+ /* 100=4 for phase A */
+ /* 110=6 for phase B */
+ }
+ }
+ assert(tmp >= 0 && tmp < 8);
+ *bits = lrsns_ltp_bits[tmp]; /* one of { 2,2, 7,7 , 6,6, 7,7} */
+ /* tmp=idx is 0,1 2,3 4,5, 6,7 */
+
+ assert(*bits == 2 || *bits == 6 || *bits == 7);
+ }
+#endif
+#else
+ assert(*bits == 1 || *bits == 11);
+#endif
+
+ if (frame_dms < LC3PLUS_FRAME_DURATION_10MS) {
+#if defined (CR9_C_ADD_1p25MS)
+ move_float(&mem_norm_corr_past[1], &mem_norm_corr_past[0], LEN_MEM_NORMCORR-1);
+#else
*mem_norm_corr_past_past = *mem_norm_corr_past;
+#endif
}
*mem_norm_corr_past = norm_corr;
diff --git a/lib_lc3plus/ltpf_decoder.c b/lib_lc3plus/ltpf_decoder.c
index 3ccd452bcb2f367c69ea1e9de832243cc309a81e..48aa9a2d706044eadff0ad1f69d38c3d44319c8f 100644
--- a/lib_lc3plus/ltpf_decoder.c
+++ b/lib_lc3plus/ltpf_decoder.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,30 +11,130 @@
#include "wmc_auto.h"
#include "functions.h"
+#ifdef CR9_C_ADD_1p25MS
+static LC3_INT16 get_continuation (LC3_INT32 fading_case, LC3PLUS_FrameDuration frame_dms, LC3_INT32 pos, LC3_INT32 total)
+{
+ LC3_INT16 retval;
+
+ if ( frame_dms != LC3PLUS_FRAME_DURATION_1p25MS )
+ {
+ retval = 0;
+ }
+ else
+ {
+ if ( pos == total )
+ {
+ retval = 0;
+ }
+ else
+ {
+ retval = fading_case;
+ }
+ }
+
+ return retval;
+}
+#endif
+
+#ifdef LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+#ifdef LTPF_PRINT_PARAMS
+static bool compare_normalized_corrs(LC3_FLOAT const *sig, LC3_INT32 len, LC3_INT32 pitch_int, LC3_INT32 mem_pitch_int, LC3_FLOAT *corr, LC3_FLOAT *corr_prev)
+#else
+static bool compare_normalized_corrs(LC3_FLOAT const *sig, LC3_INT32 len, LC3_INT32 pitch_int, LC3_INT32 mem_pitch_int)
+#endif
+{
+ LC3_FLOAT norm_0, norm_t, norm_t_prev, xcorr, xcorr_prev;
+ norm_0 = norm_t = norm_t_prev = xcorr = xcorr_prev = 0;
+
+ for ( int i=0; i < len; i++ )
+ {
+ norm_0 += sig[i] * sig[i];
+ norm_t += sig[i - pitch_int] * sig[i - pitch_int];
+ xcorr += sig[i] * sig[i - pitch_int];
+
+ norm_t_prev += sig[i - mem_pitch_int] * sig[i - mem_pitch_int];
+ xcorr_prev += sig[i] * sig[i - mem_pitch_int];
+ }
+
+ xcorr = MIN( 1.f, MAX( 0.f, xcorr / ( LC3_SQRT( norm_0 * norm_t ) + 1.00e-05f ) ) );
+ xcorr_prev = MIN( 1.f, MAX( 0.f, xcorr_prev / ( LC3_SQRT( norm_0 * norm_t_prev ) + 1.00e-05f ) ) );
+
+#ifdef LTPF_PRINT_PARAMS
+ *corr = xcorr;
+ *corr_prev = xcorr_prev;
+#endif
+
+ if ( xcorr_prev - xcorr > 5e-4 )
+ {
+ return true;
+ }
+
+ return false;
+}
+#endif
+
void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y,
LC3_INT* mem_pitch_int, LC3_INT* mem_pitch_fr, LC3_FLOAT* mem_gain, LC3_INT* mem_beta_idx, LC3_INT bfi,
- LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod,
- LC3_FLOAT damping
- , LC3_INT *mem_ltpf_active
- , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3_INT frame_dms
-)
+ LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT *conf_beta, LC3_INT concealMethod, LC3_FLOAT damping
+ , LC3_INT *mem_ltpf_active
+ , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3PLUS_FrameDuration frame_dms
+#ifdef CR9_C_ADD_1p25MS
+ , LC3_INT16* mem_continuation, LC3_INT32* mem_param_prev, LC3_INT16* mem_pitch_int_prev,
+ LC3_INT16* mem_pitch_fr_prev, LC3_INT32* mem_beta_idx_prev, LC3_FLOAT* mem_gain_prev,
+ LC3_INT16* pitch_stability_counter,
+ LC3_FLOAT* gain_step,
+ LC3_FLOAT conf_beta_max
+#endif
+ )
{
LC3_INT i, j, n, N, L_past_x, N4, N34,
pitch_int, pitch_fr, p1, p2, L_past_y, inter_len, tilt_len = 0,
- tilt_len_r, inter_len_r, old_x_len, old_y_len;
+ tilt_len_r, inter_len_r, old_x_len, old_y_len, fading_case, N4_D, N4_S;
LC3_FLOAT conf_alpha, gain, a1[12], a2[12], b1[11], b2[11],
buf_x[4 * MAX_LEN], buf_y[4 * MAX_LEN], buf_z[4 * MAX_LEN], pitch, sum1, sum2;
LC3_FLOAT *p_x, *p_y, *p_y2, *p_x_init, *p_y_init, *p_a1, *p_b1, *p_a2, *p_b2, fade_fac, current_fade_fac_up, current_fade_fac_down;
- LC3_FLOAT pitch_fl_c_old, pitch_delta;
+ LC3_FLOAT pitch_delta;
const LC3_FLOAT *inter_filter[4], *tilt_filter[4];
+#ifdef LTPF_ADAPTIVE_GAIN
+ bool ltpf_active = false;
+ bool ltpf_active_prev = false;
+ bool pitch_changed = false;
+ bool pitch_was_stable = false;
+#endif
+#ifdef LTPF_ADAPTIVE_GAIN
+ LC3_INT32 original_param[3];
+ LC3_INT32 original_pitch_int, original_pitch_fr;
+ LC3_FLOAT original_gain;
+
+#ifdef LTPF_PRINT_PARAMS
+ static int local_frame = 0;
+#ifdef LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+ LC3_FLOAT xcorr, xcorr_prev;
+#endif
+#endif
+#endif
+
+#ifdef FIX_LTPF_DEC_FLFX_MISMATCH
+ UNUSED(mem_ltpf_active);
+ fading_case = 0;
+#endif
+ tilt_len = 0;
+ conf_alpha = 0.85;
+ p1 = 0;
+ p2 = 0;
+
#ifdef WMOPS
push_wmops("process_ltpf_decoder_fl");
#endif
- pitch_fl_c_old = (LC3_FLOAT) *mem_pitch_int + (LC3_FLOAT)*mem_pitch_fr / 4.0;
- conf_alpha = 0.85;
-
+
+#ifdef FIX_LTPF_1p25
+ if (param[2] == -1) {
+ param[1] = 0;
+ param[0] = 0;
+ }
+#endif
if (bfi != 1) {
/* Decode pitch */
if (param[0] == 1) {
@@ -55,7 +155,7 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
pitch = ((LC3_FLOAT)pitch_int + (LC3_FLOAT)pitch_fr / 4.0) * (LC3_FLOAT)fs / 12800.0;
pitch = round(pitch * 4.0) / 4.0;
pitch_int = floor(pitch);
- pitch_fr = (LC3_INT)((pitch - (LC3_FLOAT)pitch_int) * 4.0);
+ pitch_fr = (LC3_INT)((pitch - (LC3_FLOAT)pitch_int) * 4.0);
} else {
pitch_int = 0;
pitch_fr = 0;
@@ -67,12 +167,16 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
}
if (param[1] == 1) {
- gain = conf_beta;
+ gain = *conf_beta;
} else {
gain = 0;
}
}
- else if (concealMethod > 0) {
+ else if ((concealMethod > 0)
+#ifdef CR9_C_ADD_1p25MS
+ && (*mem_continuation == 0)
+#endif
+ ) {
if (conf_beta_idx < 0) {
if (mem_param[1] && *mem_beta_idx >= 0)
{
@@ -92,9 +196,40 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
pitch_fr = *mem_pitch_fr;
gain = (LC3_FLOAT) *mem_gain * damping;
}
+
+#ifdef CR9_C_ADD_1p25MS
+ if (*mem_continuation)
+ {
+#ifdef LTPF_ADAPTIVE_GAIN
+ /* Save original LTPF parameters */
+ move_int(original_param, param, 3);
+ original_pitch_int = pitch_int;
+ original_pitch_fr = pitch_fr;
+ original_gain = gain;
+#endif
- if ((conf_beta <= 0) && (*mem_ltpf_active == 0))
- {
+ fading_case = *mem_continuation;
+ move_int(param, mem_param, 3);
+ pitch_int = *mem_pitch_int;
+ pitch_fr = *mem_pitch_fr;
+ gain = *mem_gain;
+#ifdef FIX_LTPF_1p25
+ conf_beta_idx = *mem_beta_idx;
+#endif
+
+ move_int(mem_param, mem_param_prev, 3);
+ *mem_pitch_int = *mem_pitch_int_prev;
+ *mem_pitch_fr = *mem_pitch_fr_prev;
+ *mem_gain = *mem_gain_prev;
+#ifdef FIX_LTPF_1p25
+ *mem_beta_idx = *mem_beta_idx_prev;
+#endif
+
+ }
+#endif
+
+ if ( fs <= 48000 )
+ {
if (fs == 8000 || fs == 16000) {
tilt_len = 4 - 2;
}
@@ -108,16 +243,196 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
tilt_len = 12 - 2;
}
+ inter_len = MAX(fs, 16000) / 8000;
+
+ /* Init buffers */
+ N = xLen;
+ old_x_len = tilt_len;
+ old_y_len = ceil(228.0 * fs / 12800.0) + inter_len;
+ L_past_x = old_x_len;
+
+ move_float(buf_x, mem_old_x, old_x_len);
+ move_float(&buf_x[old_x_len], x, xLen);
+ L_past_y = old_y_len;
+ move_float(buf_y, mem_old_y, old_y_len);
+ move_float(&buf_y[old_y_len], x, xLen);
+ }
+#ifdef LTPF_ADAPTIVE_GAIN
+ if ( frame_dms == LC3PLUS_FRAME_DURATION_1p25MS )
+ {
+ conf_alpha = 0.98;
+
+ /* Control variables */
+ ltpf_active = param[1];
+ ltpf_active_prev = mem_param[1];
+ pitch_changed = !( ( pitch_int == *mem_pitch_int ) && ( pitch_fr == *mem_pitch_fr ) );
+ pitch_was_stable = ( ( *pitch_stability_counter >= LTPF_PITCH_STABILITY_THRESHOLD ) );
+
+#ifdef CR9_C_ADD_1p25MS
+ if ( *mem_continuation == 0 )
+ {
+#endif
+#ifdef LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+ if ( !pitch_was_stable && pitch_changed && pitch_int != 0 && *mem_pitch_int != 0 )
+ {
+#ifdef LTPF_PRINT_PARAMS
+ pitch_was_stable = compare_normalized_corrs(buf_y + L_past_y, xLen, pitch_int, *mem_pitch_int, &xcorr, &xcorr_prev);
+#else
+ pitch_was_stable = compare_normalized_corrs(buf_y + L_past_y, xLen, pitch_int, *mem_pitch_int);
+#endif
+ }
+#endif
+
+ if ( ltpf_active && !pitch_changed )
+ {
+ /* increment gain and increment pitch stability counter */
+ gain = pitch_was_stable ? MIN( conf_beta_max, MAX( gain, *mem_gain ) + *gain_step ) : MAX( gain, *mem_gain );
+ ( *pitch_stability_counter )++;
+ }
+ else if ( ltpf_active && pitch_changed && !pitch_was_stable )
+ {
+ /* decrement gain and reset pitch stability counter */
+ gain = ( *mem_gain > gain ) ? MAX( gain, *mem_gain - ( conf_beta_max / LTPF_ADAPTIVE_GAIN_RATE ) ) : gain;
+ *pitch_stability_counter = 0;
+ }
+ else if ( !ltpf_active && !pitch_was_stable && ltpf_active_prev && pitch_changed )
+ {
+ /* decrement gain, use previous pitch and reset pitch stability counter */
+ gain = *mem_gain - *gain_step;
+
+#ifdef FIX_LTPF_1p25
+ if (*conf_beta > 0 && (gain - *conf_beta) > -(20.f/(1<<15)))
+#else
+ if ( (gain - *conf_beta) > -(20.f/(1<<15)))
+#endif
+ {
+ move_int( param, mem_param, 3 );
+ pitch_int = *mem_pitch_int;
+ pitch_fr = *mem_pitch_fr;
+ }
+ else
+ {
+ gain = 0.f;
+ }
+ *pitch_stability_counter = 0;
+ }
+ else if ( ( ltpf_active && pitch_changed && pitch_was_stable ) || ( !ltpf_active && pitch_was_stable ) || ( !ltpf_active && !pitch_was_stable && ltpf_active_prev && !pitch_changed ) )
+ {
+ /* use previous pitch and gain and reset pitch stability counter */
+ move_int( param, mem_param, 3 );
+ pitch_int = *mem_pitch_int;
+ pitch_fr = *mem_pitch_fr;
+ gain = *mem_gain;
+ *pitch_stability_counter = 0;
+ }
+#ifdef CR9_C_ADD_1p25MS /* This is added here for the future when adaptive gain will be enabled for other frame sizes. */
+ }
+ else if ( *mem_continuation != 0 && original_param[1] == 1
+#ifdef FIX_PLC_CONFORM_ISSUES
+ && bfi == 0
+#endif
+ )
+ {
+ /* Code enters this block if LTPF is reenabled when adaptive gain is being applied. */
+ /* In this case, use new LTPF parameters but with a smaller gain than in the prev frame.*/
+ fading_case = 0;
+ *mem_continuation = 0;
+
+ move_int( mem_param_prev, mem_param, 3 );
+ *mem_pitch_int_prev = *mem_pitch_int;
+ *mem_pitch_fr_prev = *mem_pitch_fr;
+ *mem_gain_prev = *mem_gain;
+
+ move_int( mem_param, param, 3 );
+ *mem_pitch_int = pitch_int;
+ *mem_pitch_fr = pitch_fr;
+ *mem_gain = gain;
+
+ move_int( param, original_param, 3 );
+ pitch_int = original_pitch_int;
+ pitch_fr = original_pitch_fr;
+ gain = original_gain;
+
+ /* if prev gain > curr gain, then decrease gain slowly. */
+ gain = ( *mem_gain > gain) ? MAX( gain, *mem_gain - ( conf_beta_max / LTPF_ADAPTIVE_GAIN_RATE ) ) : gain;
+
+ *pitch_stability_counter = 0;
+ }
+#endif
+ }
+#endif /* LTPF_ADAPTIVE_GAIN */
+ if ( mem_param[1] && *mem_beta_idx < 0 )
+ {
+ mem_param[1] = 0;
+ }
+
+ if ( param[1] && conf_beta_idx < 0 )
+ {
+ param[1] = 0;
+ }
+
+ if ( fs <= 48000 )
+ {
+#ifdef FIX_LTPF_MEM_CONTINUATION
+#ifdef FIX_LTPF_DEC_FLFX_MISMATCH
+ if ( (( param[1] == 0 ) && ( mem_param[1] == 0 )) || fading_case == 1 )
+#else
+ if ( (( *conf_beta <= 0 ) && ( *mem_ltpf_active == 0 )) || fading_case == 1 )
+#endif
+#else
+ if ( ( *conf_beta <= 0 ) && ( *mem_ltpf_active == 0 ) )
+#endif
+ {
+#ifndef LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+ if ( fs == 8000 || fs == 16000 )
+ {
+ tilt_len = 4 - 2;
+ }
+ else if ( fs == 24000 )
+ {
+ tilt_len = 6 - 2;
+ }
+ else if ( fs == 32000 )
+ {
+ tilt_len = 8 - 2;
+ }
+ else if ( fs == 44100 || fs == 48000 )
+ {
+ tilt_len = 12 - 2;
+ }
N = xLen;
old_x_len = tilt_len;
inter_len = MAX(fs, 16000) / 8000;
old_y_len = ceilf((LC3_FLOAT)228.0 * fs / 12800.0) + inter_len; /* 228.0 needed to make use of ceil */
+#endif
+
+#ifdef FIX_LTPF_MEM_CONTINUATION
+#ifdef CR9_C_ADD_1p25MS
+ fading_case = 1;
+ N4 = fs * 0.0025;
+ N4_S = 0;
+ N4_D = N4;
+ if ( frame_dms == LC3PLUS_FRAME_DURATION_1p25MS )
+ {
+ N4_D = 2 * N4;
+ if ( *mem_continuation )
+ {
+ N4_S = N4;
+ }
+ }
+ *mem_continuation = get_continuation( fading_case, frame_dms, ( N4 + N4_S ), N4_D );
+#endif
+#endif
move_float(mem_old_y, &mem_old_y[N], (old_y_len - N));
move_float(&mem_old_y[old_y_len - N], x, N);
move_float(mem_old_x, &x[N - old_x_len], old_x_len);
+#ifdef FIX_LTPF_DEC_FLFX_MISMATCH
+ mem_param[1] = 0;
+#else
*mem_ltpf_active = 0;
+#endif
}
else
{
@@ -133,8 +448,10 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
tilt_filter[1] = conf_tilt_filter_16[1];
tilt_filter[2] = conf_tilt_filter_16[2];
tilt_filter[3] = conf_tilt_filter_16[3];
- tilt_len = 4 - 2;
- tilt_len_r = 3;
+#ifndef LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+ tilt_len = 4 - 2;
+#endif
+ tilt_len_r = 3;
} else if (fs == 24000) {
inter_filter[0] = conf_inter_filter_24[0];
inter_filter[1] = conf_inter_filter_24[1];
@@ -146,8 +463,10 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
tilt_filter[1] = conf_tilt_filter_24[1];
tilt_filter[2] = conf_tilt_filter_24[2];
tilt_filter[3] = conf_tilt_filter_24[3];
- tilt_len = 6 - 2;
- tilt_len_r = 5;
+#ifndef LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+ tilt_len = 6 - 2;
+#endif
+ tilt_len_r = 5;
} else if (fs == 32000) {
inter_filter[0] = conf_inter_filter_32[0];
inter_filter[1] = conf_inter_filter_32[1];
@@ -159,8 +478,10 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
tilt_filter[1] = conf_tilt_filter_32[1];
tilt_filter[2] = conf_tilt_filter_32[2];
tilt_filter[3] = conf_tilt_filter_32[3];
- tilt_len = 8 - 2;
- tilt_len_r = 7;
+#ifndef LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+ tilt_len = 8 - 2;
+#endif
+ tilt_len_r = 7;
} else if (fs == 44100 || fs == 48000) {
inter_filter[0] = conf_inter_filter_48[0];
inter_filter[1] = conf_inter_filter_48[1];
@@ -172,11 +493,14 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
tilt_filter[1] = conf_tilt_filter_48[1];
tilt_filter[2] = conf_tilt_filter_48[2];
tilt_filter[3] = conf_tilt_filter_48[3];
- tilt_len = 12 - 2;
- tilt_len_r = 11;
+#ifndef LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+ tilt_len = 12 - 2;
+#endif
+ tilt_len_r = 11;
}
- inter_len = MAX(fs, 16000) / 8000;
+#ifndef LTPF_ADAPTIVE_GAIN_WITH_NORM_CORR
+ inter_len = MAX( fs, 16000 ) / 8000;
/* Init buffers */
N = xLen;
@@ -187,9 +511,13 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
move_float(&buf_x[old_x_len], x, xLen);
L_past_y = old_y_len;
move_float(buf_y, mem_old_y, old_y_len);
- zero_float(&buf_y[old_y_len], xLen);
+ zero_float( &buf_y[old_y_len], xLen );
+#endif
N4 = fs * 0.0025;
+#ifdef CR9_C_ADD_1p25MS
+ N4 = MIN(N4, xLen);
+#endif
N34 = N - N4;
/* Init filter parameters */
@@ -198,6 +526,7 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
a1[i] = *mem_gain * inter_filter[*mem_pitch_fr][i];
}
+ assert( *mem_beta_idx >= 0 );
for (i = 0; i < tilt_len_r; i++) {
b1[i] = conf_alpha * (*mem_gain) * tilt_filter[*mem_beta_idx][i];
}
@@ -206,6 +535,7 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
}
if (param[1] == 1) {
+ assert( conf_beta_idx >= 0 );
for (i = 0; i < tilt_len_r; i++) {
b2[i] = conf_alpha * gain * tilt_filter[conf_beta_idx][i];
}
@@ -216,17 +546,53 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
p2 = pitch_int;
}
+
+#ifdef CR9_C_ADD_1p25MS
+ if (*mem_continuation == 0) {
+#endif
+ /* check fading case */
+ if (mem_param[1] == 0 && param[1] == 0) {
+ fading_case = 1;
+ } else if (mem_param[1] == 1 && param[1] == 0) {
+ fading_case = 3;
+ } else if (mem_param[1] == 0 && param[1] == 1) {
+ fading_case = 2;
+ } else if (*mem_pitch_int == pitch_int && *mem_pitch_fr == pitch_fr) {
+ fading_case = 4;
+ } else {
+ fading_case = 5;
+ }
+#ifdef CR9_C_ADD_1p25MS
+ }
+#endif
+
+ N4_D = N4;
+ UNUSED(N4_D); UNUSED(N4_S);
+ N4_S = 0;
+#ifdef CR9_C_ADD_1p25MS
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ N4_D = 2*N4;
+ if (*mem_continuation)
+ {
+ N4_S = N4;
+ }
+ }
+#endif
/* First quarter of the current frame: cross-fading */
- fade_fac = 1. / (LC3_FLOAT) N4;
- current_fade_fac_up = 0.f;
- current_fade_fac_down = 1.f;
+ fade_fac = 1. / (LC3_FLOAT) N4_D;
+ current_fade_fac_up = N4_S*fade_fac;
+ current_fade_fac_down = 1.f - current_fade_fac_up;
(void) p_x; (void) p_y; (void) p_a1; (void) p_b1;
- if (mem_param[1] == 0 && param[1] == 0) {
+ if (fading_case == 1) {
+
memmove(&buf_y[L_past_y], &buf_x[L_past_x], sizeof(LC3_FLOAT) * N4);
-
- } else if (mem_param[1] == 1 && param[1] == 0) {
+#if defined( CR9_C_ADD_1p25MS ) && defined( FIX_LTPF_MEM_CONTINUATION )
+ *mem_continuation = get_continuation(fading_case, frame_dms, (N4+N4_S), N4_D);
+#endif
+ } else if (fading_case == 3) {
for (n = 0; n < N4; n++) {
sum1 = 0;
sum2 = 0;
@@ -246,8 +612,10 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
current_fade_fac_down * sum2;
current_fade_fac_down -= fade_fac;
}
-
- } else if (mem_param[1] == 0 && param[1] == 1) {
+#ifdef CR9_C_ADD_1p25MS
+ *mem_continuation = get_continuation(fading_case, frame_dms, (n+N4_S), N4_D);
+#endif
+ } else if (fading_case == 2) {
for (n = 0; n < N4; n++) {
sum1 = 0;
sum2 = 0;
@@ -266,7 +634,10 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
buf_y[L_past_y + n] = buf_x[L_past_x + n] - current_fade_fac_up * sum1 + current_fade_fac_up * sum2;
current_fade_fac_up += fade_fac;
}
- } else if (*mem_pitch_int == pitch_int && *mem_pitch_fr == pitch_fr) {
+#ifdef CR9_C_ADD_1p25MS
+ *mem_continuation = get_continuation(fading_case, frame_dms, (n+N4_S), N4_D);
+#endif
+ } else if (fading_case == 4) {
for (n = 0; n < N4; n++) {
sum1 = 0;
sum2 = 0;
@@ -284,6 +655,9 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
buf_y[L_past_y + n] = buf_x[L_past_x + n] - sum1 + sum2;
}
+#ifdef CR9_C_ADD_1p25MS
+ *mem_continuation = get_continuation(fading_case, frame_dms, (n+N4_S), N4_D);
+#endif
} else {
p_x_init = &buf_x[L_past_x];
p_y_init = &buf_y[L_past_y - p1 + inter_len - 1];
@@ -346,6 +720,9 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
p_y_init++;
p_y2++;
}
+#ifdef CR9_C_ADD_1p25MS
+ *mem_continuation = get_continuation(fading_case, frame_dms, (n+N4_S), N4_D);
+#endif
}
/* Second quarter of the current frame */
@@ -389,19 +766,37 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f
move_float(mem_old_x, &buf_x[N], old_x_len);
move_float(mem_old_y, &buf_y[N], old_y_len);
- *mem_ltpf_active = (conf_beta > 0);
+#ifndef FIX_LTPF_DEC_FLFX_MISMATCH
+ *mem_ltpf_active = ( *conf_beta > 0 );
+#endif
+ }
+ }
+
+
+ if ( bfi == 0 && hrmode == 1 && ( frame_dms == LC3PLUS_FRAME_DURATION_5MS || frame_dms == LC3PLUS_FRAME_DURATION_2p5MS ) )
+ {
+ pitch_delta = LC3_FABS( (LC3_FLOAT) *mem_pitch_int + (LC3_FLOAT) ( *mem_pitch_fr / 4.0 ) - (LC3_FLOAT) pitch_int - (LC3_FLOAT) ( pitch_fr / 4.0 ) );
+ *rel_pitch_change = pitch_delta / MAX( (LC3_FLOAT) *mem_pitch_int + (LC3_FLOAT) ( *mem_pitch_fr / 4.0 ), 1 );
}
+#ifdef CR9_C_ADD_1p25MS
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ move_int(mem_param_prev, mem_param, 3);
+ *mem_pitch_int_prev = *mem_pitch_int;
+ *mem_pitch_fr_prev = *mem_pitch_fr;
+ *mem_gain_prev = *mem_gain;
+ *mem_beta_idx_prev = *mem_beta_idx;
+ }
+#endif
+
/* Update ltpf param memory */
move_int(mem_param, param, 3);
*mem_pitch_int = pitch_int;
*mem_pitch_fr = pitch_fr;
*mem_gain = gain;
*mem_beta_idx = conf_beta_idx;
- if (bfi == 0 && hrmode == 1 && (frame_dms == 50 || frame_dms == 25)){
- pitch_delta = LC3_FABS(pitch_fl_c_old - (LC3_FLOAT)pitch_int - (LC3_FLOAT)(pitch_fr / 4.0));
- *rel_pitch_change = pitch_delta / MAX(pitch_fl_c_old, 1);
- }
+
#ifdef WMOPS
pop_wmops();
diff --git a/lib_lc3plus/mdct.c b/lib_lc3plus/mdct.c
index 4698afd4bfb043409a1736db099373ea210d7eb5..94e6cada27a2692e28db77ccf9dcd1d4e0a2de7b 100644
--- a/lib_lc3plus/mdct.c
+++ b/lib_lc3plus/mdct.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,9 +11,9 @@
#include "wmc_auto.h"
#include "functions.h"
-static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT hrmode)
+static const LC3_FLOAT* mdct_window(LC3_INT length, LC3PLUS_FrameDuration frame_dms, LC3_INT hrmode)
{
- if (frame_dms == 100) {
+ if (frame_dms == LC3PLUS_FRAME_DURATION_10MS) {
switch (length) {
case 80:
return MDCT_WINS_10ms[hrmode][0];
@@ -31,7 +31,7 @@ static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT h
return NULL;
}
}
- else if (frame_dms == 75) {
+ else if (frame_dms == LC3PLUS_FRAME_DURATION_7p5MS) {
switch (length) {
case 60:
return MDCT_WINS_7_5ms[hrmode][0];
@@ -49,7 +49,7 @@ static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT h
return NULL;
}
}
- else if (frame_dms == 50) {
+ else if (frame_dms == LC3PLUS_FRAME_DURATION_5MS) {
switch (length) {
case 40:
return MDCT_WINS_5ms[hrmode][0];
@@ -67,7 +67,7 @@ static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT h
return NULL;
}
}
- else if (frame_dms == 25) {
+ else if (frame_dms == LC3PLUS_FRAME_DURATION_2p5MS) {
switch (length) {
case 20:
return MDCT_WINS_2_5ms[hrmode][0];
@@ -85,31 +85,56 @@ static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT h
return NULL;
}
}
+#ifdef CR9_C_ADD_1p25MS
+ else if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ switch (length) {
+ case 10:
+ return MDCT_WINS_1_25ms[hrmode][0];
+ case 20:
+ return MDCT_WINS_1_25ms[hrmode][1];
+ case 30:
+ return MDCT_WINS_1_25ms[hrmode][2];
+ case 40:
+ return MDCT_WINS_1_25ms[hrmode][3];
+ case 60:
+ return MDCT_WINS_1_25ms[hrmode][4];
+ default:
+ return NULL;
+ }
+ }
+#endif
return NULL;
}
-void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC3_INT hrmode)
+void mdct_init(Mdct* mdct, LC3_INT length, LC3PLUS_FrameDuration frame_dms, LC3_INT fs_idx, LC3_INT hrmode)
{
- if (frame_dms == 100) {
- mdct->leading_zeros = MDCT_la_zeroes[fs_idx];
- }
- else if (frame_dms == 75) {
- mdct->leading_zeros = MDCT_la_zeroes_7_5ms[fs_idx];
- }
- else if (frame_dms == 50) {
- mdct->leading_zeros = MDCT_la_zeroes_5ms[fs_idx];
- }
- else if (frame_dms == 25) {
+ switch (frame_dms)
+ {
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ mdct->leading_zeros = MDCT_la_zeroes_1_25ms[fs_idx];
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
mdct->leading_zeros = MDCT_la_zeroes_2_5ms[fs_idx];
- }
- else {
+ break;
+ case LC3PLUS_FRAME_DURATION_5MS:
+ mdct->leading_zeros = MDCT_la_zeroes_5ms[fs_idx];
+ break;
+ case LC3PLUS_FRAME_DURATION_7p5MS:
+ mdct->leading_zeros = MDCT_la_zeroes_7_5ms[fs_idx];
+ break;
+ case LC3PLUS_FRAME_DURATION_10MS:
+ mdct->leading_zeros = MDCT_la_zeroes[fs_idx];
+ break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
assert(!"invalid frame_ms");
}
mdct->length = length;
mdct->mem_length = length - mdct->leading_zeros;
mdct->window = mdct_window(length, frame_dms, hrmode);
- mdct->mem = calloc(sizeof(*mdct->mem), mdct->mem_length);
+ mdct->mem = calloc(mdct->mem_length, sizeof(*mdct->mem));
dct4_init(&mdct->dct, length);
}
diff --git a/lib_lc3plus/mdct_shaping.c b/lib_lc3plus/mdct_shaping.c
index 296a8cd454980560dd31f199cffabbf729f8602f..6c1b0f5dbb81a6439aa2c51e5ec4db4ade3722c7 100644
--- a/lib_lc3plus/mdct_shaping.c
+++ b/lib_lc3plus/mdct_shaping.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/near_nyquist_detector.c b/lib_lc3plus/near_nyquist_detector.c
index 5d81392b214e9c599defa76f20afdfbebf1db3bb..56f66937d2950354059acb50b66d6f45a76e5e14 100644
--- a/lib_lc3plus/near_nyquist_detector.c
+++ b/lib_lc3plus/near_nyquist_detector.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -12,7 +12,8 @@
#include "functions.h"
void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index,
- const LC3_INT bands_number, const LC3_FLOAT* ener , const LC3_INT16 frame_dms, const LC3_INT16 hrmode)
+ const LC3_INT bands_number, const LC3_FLOAT* ener
+ , const LC3PLUS_FrameDuration frame_dms, const LC3_INT16 hrmode)
{
*near_nyquist_flag = 0;
if (hrmode == 0){
@@ -36,36 +37,43 @@ void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT f
}
}
}
- else // hrmode == 1
+ else /* hrmode == 1 */
{
- // inverse spectral flatness = mean(energy) ./ 2^(mean(log2(energy)));
+ /* inverse spectral flatness = mean(energy) ./ 2^(mean(log2(energy))); */
LC3_INT32 td_thresh, i = 0;
LC3_FLOAT mean_ener = 0, mean_ener_log2 = 0, inv_flatness = 0;
switch (frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ assert(0);
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
td_thresh = TD_HR_thresh_2_5ms;
break;
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
td_thresh = TD_HR_thresh_5ms;
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
td_thresh = TD_HR_thresh_7_5ms;
break;
- default: /* 100 */
+ case LC3PLUS_FRAME_DURATION_10MS:
td_thresh = TD_HR_thresh_10ms;
break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
- // calculate arithmetic mean
+ /* calculate arithmetic mean */
for (i = 0; i < bands_number; i++)
{
mean_ener += ener[i];
}
mean_ener = mean_ener / bands_number;
- // calculate geometric mean
+ /* calculate geometric mean */
for (i = 0; i < bands_number; i++)
{
if (ener[i] != 0) {
diff --git a/lib_lc3plus/noise_factor.c b/lib_lc3plus/noise_factor.c
index 72b2602251430320fa436f899263786b1564a7e5..80adaf399cf7d675cecf1890a20cbf9df970cdbf 100644
--- a/lib_lc3plus/noise_factor.c
+++ b/lib_lc3plus/noise_factor.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,7 +11,7 @@
#include "wmc_auto.h"
#include "functions.h"
-void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms,
+void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3PLUS_FrameDuration frame_dms,
LC3_INT target_bytes
)
{
@@ -21,22 +21,30 @@ void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3
switch (frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
nTransWidth = 1;
startOffset = 6;
break;
- case 50:
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
+ nTransWidth = 1;
+ startOffset = 6;
+ break;
+ case LC3PLUS_FRAME_DURATION_5MS:
nTransWidth = 1;
startOffset = 12;
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
nTransWidth = 2;
startOffset = 18;
break;
- case 100:
+ case LC3PLUS_FRAME_DURATION_10MS:
nTransWidth = 3;
startOffset = 24;
break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
for (k = startOffset - nTransWidth; k < startOffset + nTransWidth; k++)
@@ -91,7 +99,7 @@ void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3
- if (kZeroLines > 1 && target_bytes <= 20 && frame_dms == 100) {
+ if (kZeroLines > 1 && target_bytes <= 20 && frame_dms == LC3PLUS_FRAME_DURATION_10MS) {
j = 0, k = 0, nsf1 = 0, nsf2 = 0, sumZeroLines = 0;
diff --git a/lib_lc3plus/noise_filling.c b/lib_lc3plus/noise_filling.c
index f929338d0cabb0903ef6d4339496410e6bab3bbd..77eca88c810365623db5eee5a74fe1dfabb1a54c 100644
--- a/lib_lc3plus/noise_filling.c
+++ b/lib_lc3plus/noise_filling.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,30 +11,38 @@
#include "wmc_auto.h"
#include "functions.h"
-void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx)
+void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3PLUS_FrameDuration frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx)
{
LC3_INT zeroLines[MAX_LEN];
- LC3_INT nTransWidth, startOffset, j, k, nzeros = 0, kZeroLines;
+ LC3_INT nTransWidth = 0, startOffset = 0, j, k, nzeros = 0, kZeroLines;
LC3_FLOAT fac_ns = 0;
switch (frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
nTransWidth = 1;
startOffset = 6;
break;
- case 50:
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
+ nTransWidth = 1;
+ startOffset = 6;
+ break;
+ case LC3PLUS_FRAME_DURATION_5MS:
nTransWidth = 1;
startOffset = 12;
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
nTransWidth = 2;
startOffset = 18;
break;
- case 100:
+ case LC3PLUS_FRAME_DURATION_10MS:
nTransWidth = 3;
startOffset = 24;
break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
fac_ns = (8.0 - fac_ns_idx) / 16.0;
diff --git a/lib_lc3plus/olpa.c b/lib_lc3plus/olpa.c
index 976f0a177e059c26a1b14ff3261c13742751506c..aacbdd34fbcbdc2a42d87798f57666998320f30d 100644
--- a/lib_lc3plus/olpa.c
+++ b/lib_lc3plus/olpa.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -46,8 +46,8 @@ LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len)
}
void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0,
- LC3_INT* pitch_flag,
- LC3_INT* T0_out, LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms)
+ LC3_INT* pitch_flag,
+ LC3_INT* T0_out, LC3_FLOAT* normcorr_out, LC3_INT len, LC3PLUS_FrameDuration frame_dms)
{
LC3_FLOAT norm_corr = 0, sum = 0, sum0 = 0, sum1 = 0, sum2 = 0, norm_corr2 = 0, *s6k4;
LC3_FLOAT buf[LEN_6K4 + MAX_PITCH_6K4 + MAX_LEN], R0[RANGE_PITCH_6K4]; /* constant length */
@@ -56,15 +56,21 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4
len2 = len / 2;
switch(frame_dms)
{
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
delta = len / 2;
acflen = len2 * 2;
break;
- case 25:
+ case LC3PLUS_FRAME_DURATION_2p5MS:
delta = 3*(len /2);
acflen = len2*4;
break;
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ delta = 7 * (len / 2);
+ acflen = len2 * 8;
+ break;
+#endif
default:
delta = 0;
@@ -84,6 +90,7 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4
move_float(&buf[mem_in_len], R0, len2);
move_float(buf, mem_s6k4, mem_in_len);
move_float(mem_s6k4, &buf[len2], mem_in_len);
+
for (i = MIN_PITCH_6K4; i <= MAX_PITCH_6K4; i++) {
sum = mac_loop(s6k4, &s6k4[-i], acflen);
R0[i - MIN_PITCH_6K4] = sum;
@@ -137,10 +144,10 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4
switch(frame_dms)
{
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
if (*pitch_flag == 1)
{
- *mem_old_T0 = T0;
+ *mem_old_T0 = T0;
*pitch_flag = 0;
}
else
@@ -149,10 +156,10 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4
}
break;
- case 25:
+ case LC3PLUS_FRAME_DURATION_2p5MS:
if (*pitch_flag == 3)
{
- *mem_old_T0 = T0;
+ *mem_old_T0 = T0;
*pitch_flag = 0;
}
else
@@ -160,6 +167,19 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4
*pitch_flag += 1;
}
break;
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ if (*pitch_flag == 7)
+ {
+ *mem_old_T0 = T0;
+ *pitch_flag = 0;
+ }
+ else
+ {
+ *pitch_flag += 1;
+ }
+ break;
+#endif
default:
*mem_old_T0 = T0;
@@ -167,5 +187,4 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4
*T0_out = T0 * 2.0;
*normcorr_out = norm_corr;
-
}
diff --git a/lib_lc3plus/pc_apply.c b/lib_lc3plus/pc_apply.c
index a7113f1bc781f7e35e3d5852a95482591bac0ab3..9ae4a724dab81cb84b3b3f90553bde2c622b9ba8 100644
--- a/lib_lc3plus/pc_apply.c
+++ b/lib_lc3plus/pc_apply.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/pc_classify.c b/lib_lc3plus/pc_classify.c
index adb8a59713ef84fcd84f8abf7a6481a08030be38..628cb9d12d525b8f00bcaf90b4e5d164b6d1122c 100644
--- a/lib_lc3plus/pc_classify.c
+++ b/lib_lc3plus/pc_classify.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -13,14 +13,14 @@
LC3_FLOAT pc_peak_detector(LC3_FLOAT *q_d_prev, LC3_INT32 yLen);
-void processPcClassify_fl(LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi)
+void processPcClassify_fl(LC3_INT32 pitch_present, LC3PLUS_FrameDuration frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi)
{
LC3_INT32 maxPitchBin, xover, i;
LC3_FLOAT part_nrg, full_nrg;
part_nrg = 0; full_nrg = 0;
- if (spec_inv_idx < (4 * frame_dms / 10))
+ if (spec_inv_idx < (4 * frame_dms * 1.25))
{
if (stab_fac < 0.5)
{
@@ -28,7 +28,7 @@ void processPcClassify_fl(LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOA
} else if (pitch_present == 1)
{
maxPitchBin = 8;
- if (frame_dms == 50)
+ if (frame_dms == LC3PLUS_FRAME_DURATION_5MS)
{
maxPitchBin = 4;
}
diff --git a/lib_lc3plus/pc_main.c b/lib_lc3plus/pc_main.c
index 5ef1676d4838b5a814c5f51e1ceb5373184a5837..28c065f6dbfc542fc010c499da7f3751d651069a 100644
--- a/lib_lc3plus/pc_main.c
+++ b/lib_lc3plus/pc_main.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/pc_update.c b/lib_lc3plus/pc_update.c
index b24b2ea62a6848a876b85917fc41e6a090e82a2b..35166e1780d4d6e2453f20542a772baa78c5274b 100644
--- a/lib_lc3plus/pc_update.c
+++ b/lib_lc3plus/pc_update.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/per_band_energy.c b/lib_lc3plus/per_band_energy.c
index 413b6cfd844e28d319d9fbd59032f95ff9dd5df4..fe1e31f66f92df48ddff29b382e0003007f72c8c 100644
--- a/lib_lc3plus/per_band_energy.c
+++ b/lib_lc3plus/per_band_energy.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,7 +11,7 @@
#include "wmc_auto.h"
#include "functions.h"
-void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d)
+void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3PLUS_FrameDuration frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d)
{
LC3_INT i, j, start, stop, maxBwBin;
LC3_FLOAT sum;
@@ -30,15 +30,24 @@ void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_
}
switch (frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ maxBwBin = maxBwBin >> 3;
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
maxBwBin = maxBwBin >> 2;
break;
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
maxBwBin = maxBwBin >> 1;
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
maxBwBin = (maxBwBin >> 2) * 3;
break;
+ case LC3PLUS_FRAME_DURATION_10MS:
+ break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
for (i = 0; i < bands_number; i++) {
diff --git a/lib_lc3plus/plc_classify.c b/lib_lc3plus/plc_classify.c
index f1f1878d4bf644657eaaa09bbdcce8f976b633d6..6ab043abe827a83e9f35e084bb9430777c023690 100644
--- a/lib_lc3plus/plc_classify.c
+++ b/lib_lc3plus/plc_classify.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -83,23 +83,58 @@ static void array_calculate(LC3_INT32 *array_tdc, LC3_INT32 *array_ns, int lengt
*counter_ns = counter_loc_ns;
}
-static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr);
+static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength, LC3PLUS_FrameDuration frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr);
static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *bands_offset, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc);
void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *nbLostCmpt, LC3_INT32 bfi,
- LC3_FLOAT *xcorr, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 pitch_int,
+ LC3_FLOAT *xcorr, LC3_INT32 framelength, LC3PLUS_FrameDuration frame_dms, LC3_INT32 pitch_int,
LC3_INT32 fs, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 tilt, PlcAdvSetup *plcAd
, LC3_INT32 hrmode
)
{
LC3_FLOAT sc, class;
int fs_idx_tmp;
+#ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+ LC3_INT16 resetClassifierThreshold = 0;
+ LC3_INT16 updateStatistics = 0;
+#endif
if (plcAd)
{
*xcorr = 0;
}
+#ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+ switch (frame_dms)
+ {
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ resetClassifierThreshold = 16;
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
+ resetClassifierThreshold = 8;
+ break;
+ case LC3PLUS_FRAME_DURATION_5MS:
+ resetClassifierThreshold = 4;
+ break;
+ case LC3PLUS_FRAME_DURATION_7p5MS:
+ resetClassifierThreshold = 3;
+ break;
+ case LC3PLUS_FRAME_DURATION_10MS:
+ resetClassifierThreshold = 2;
+ break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED: assert(0);
+ }
+
+ if (plcAd->numberOfGoodFrames > resetClassifierThreshold)
+ {
+ updateStatistics = 1;
+ } else {
+ updateStatistics = 0;
+ }
+#endif
+
fs_idx_tmp = FS2FS_IDX(fs);
/* Save statistics for 24 kHz, 48 kHz and 96 kHz */
if ((bfi == 1) || ((bfi >= 0) && (bfi <= 2) && ((fs_idx_tmp == 2) || (fs_idx_tmp == 4) || (fs_idx_tmp == 5)))) /* Partial Concealment PC(bfi==2) requires allowing value 2 to pass thru as well */
@@ -126,34 +161,70 @@ void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *n
if (class <= 0)
{
- if (frame_dms == 100 && hrmode == 0)
+ if (frame_dms == LC3PLUS_FRAME_DURATION_10MS && hrmode == 0)
{
*concealMethod = 2; /* PhaseEcu selected */
- array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
- array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+
+#ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+ if (updateStatistics == 1)
+#endif
+ {
+ array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ }
}
else
{
- array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
- array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+#ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+ if (updateStatistics == 1)
+#endif
+ {
+ array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ }
}
}
else {
- array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 1, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
- array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+#ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+ if (updateStatistics == 1)
+#endif
+ {
+ array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 1, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ }
}
}
else
{
*concealMethod = 4; /* Noise Substitution */
- array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
- array_insert_and_shift(plcAd->plc_longterm_advc_ns, 1, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+
+#ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+ if (updateStatistics == 1)
+#endif
+ {
+ array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ array_insert_and_shift(plcAd->plc_longterm_advc_ns, 1, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ }
}
- array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, plcAd->longterm_analysis_counter_max);
- update_bit_and_byte_positions(plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+#ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+ if (updateStatistics == 1)
+#endif
+ {
+ array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, plcAd->longterm_analysis_counter_max);
+ update_bit_and_byte_positions(plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ }
}
}
+
+#ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+ if (bfi == 1)
+ {
+ plcAd->numberOfGoodFrames = 0;
+ } else {
+ plcAd->numberOfGoodFrames = plcAd->numberOfGoodFrames + 1;
+ }
+#endif
}
static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc)
@@ -234,7 +305,7 @@ static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT
}
static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength,
- LC3_INT32 frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr)
+ LC3PLUS_FrameDuration frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr)
{
LC3_INT32 max_corr_len, pitch_min, corr_len, min_corr_len, pcm_max_corr_len, range1Start, range2Start, i;
LC3_FLOAT norm_w, norm_w_t;
@@ -252,7 +323,7 @@ static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_I
pcm_max_corr_len = max_len_pcm_plc - pitch_int;
min_corr_len = 2 * pitch_min; /* at least 5 ms (=2*pitchmin*) corr length */
- max_corr_len = framelength*100/frame_dms; /* maximum 10 ms */
+ max_corr_len = framelength*100/(frame_dms*1.25*10); /* maximum 10 ms */
max_corr_len = MIN( max_corr_len, pcm_max_corr_len );
corr_len = MIN( max_corr_len, pitch_int ); /* pitch_int is prefered, but maximum 10ms or left pcm buf size */
diff --git a/lib_lc3plus/plc_compute_stab_fac.c b/lib_lc3plus/plc_compute_stab_fac.c
index 121c2f06a22d58316ff9259997dd435c3b8b7b2d..cd5a95441b438fc2b6429bb8a18d82898d09c9ad 100644
--- a/lib_lc3plus/plc_compute_stab_fac.c
+++ b/lib_lc3plus/plc_compute_stab_fac.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_damping_scrambling.c b/lib_lc3plus/plc_damping_scrambling.c
index ac4526b4ec698c7a90fca4e71c832dbf54245117..edd430335d5c77305c6e2ae7957d6166f887ac62 100644
--- a/lib_lc3plus/plc_damping_scrambling.c
+++ b/lib_lc3plus/plc_damping_scrambling.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -15,7 +15,7 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed,
LC3_INT32 *pc_seed, LC3_INT32 ns_nbLostCmpt_pc,
LC3_INT32 ns_nbLostCmpt, LC3_FLOAT *stabFac, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast,
LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi,
- LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2,
+ LC3PLUS_FrameDuration frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2,
LC3_FLOAT *cum_fflcAtten
, LC3_UINT8 plc_fadeout_type
)
@@ -59,7 +59,7 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed,
}
void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb,
- LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow,
+ LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3PLUS_FrameDuration frame_dms, LC3_FLOAT *cum_fading_slow,
LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx
, LC3_UINT8 plc_fadeout_type
)
@@ -74,18 +74,28 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n
switch (frame_dms)
{
- case 25:
- slow = LC3_SQRT(LC3_SQRT(slow));
- fast = LC3_SQRT(LC3_SQRT(fast));
- break;
- case 50:
- slow = LC3_SQRT(slow);
- fast = LC3_SQRT(fast);
- break;
- case 75:
- slow = LC3_SQRT(LC3_SQRT(slow*slow*slow));
- fast = LC3_SQRT(LC3_SQRT(fast*fast*fast));
- break;
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ slow = LC3_SQRT(LC3_SQRT(LC3_SQRT(slow)));
+ fast = LC3_SQRT(LC3_SQRT(LC3_SQRT(fast)));
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
+ slow = LC3_SQRT(LC3_SQRT(slow));
+ fast = LC3_SQRT(LC3_SQRT(fast));
+ break;
+ case LC3PLUS_FRAME_DURATION_5MS:
+ slow = LC3_SQRT(slow);
+ fast = LC3_SQRT(fast);
+ break;
+ case LC3PLUS_FRAME_DURATION_7p5MS:
+ slow = LC3_SQRT(LC3_SQRT(slow*slow*slow));
+ fast = LC3_SQRT(LC3_SQRT(fast*fast*fast));
+ break;
+ case LC3PLUS_FRAME_DURATION_10MS:
+ break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
if (plc_fadeout_type == 0)
@@ -98,10 +108,10 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n
{
if (plc_fadeout_type != 0)
{
- if (nbLostCmpt < (4 * (100.0 / (LC3_FLOAT)frame_dms))) {
+ if (nbLostCmpt < (4 * (100.0 / (LC3_FLOAT)(frame_dms*1.25*10)))) {
cum_fading_slow_local = 1.0;
}
- else if (nbLostCmpt < (8 * (100.0 / (LC3_FLOAT)frame_dms))) {
+ else if (nbLostCmpt < (8 * (100.0 / (LC3_FLOAT)(frame_dms*1.25*10)))) {
cum_fading_slow_local = 0.9;
}
else {
@@ -118,23 +128,27 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n
if (spec_inv_idx == 0)
{
- if (nbLostCmpt * frame_dms > PLC_FADEOUT_IN_MS * 10)
+ if (nbLostCmpt * frame_dms * 1.25 * 10 > PLC_FADEOUT_IN_MS * 10)
{
fflcAtten = 0;
*cum_fflcAtten = 0;
}
- else if (nbLostCmpt * frame_dms > 200)
+ else if (nbLostCmpt * frame_dms * 1.25 * 10 > 200)
{
switch (frame_dms)
{
- case 25: fflcAtten = PLC34_ATTEN_FAC_025; break;
- case 50: fflcAtten = PLC34_ATTEN_FAC_050; break;
- case 75: fflcAtten = PLC34_ATTEN_FAC_075; break;
- case 100: fflcAtten = PLC34_ATTEN_FAC_100; break;
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS: fflcAtten = PLC34_ATTEN_FAC_0125; break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS: fflcAtten = PLC34_ATTEN_FAC_025; break;
+ case LC3PLUS_FRAME_DURATION_5MS: fflcAtten = PLC34_ATTEN_FAC_050; break;
+ case LC3PLUS_FRAME_DURATION_7p5MS: fflcAtten = PLC34_ATTEN_FAC_075; break;
+ case LC3PLUS_FRAME_DURATION_10MS: fflcAtten = PLC34_ATTEN_FAC_100; break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
}
-
*cum_fflcAtten = *cum_fflcAtten * fflcAtten;
cum_fading_slow_local = *cum_fading_slow * *cum_fflcAtten;
cum_fading_fast_local = *cum_fading_fast * *cum_fflcAtten;
@@ -145,10 +159,10 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n
plc_start_inFrames = 1;
}
else {
- plc_start_inFrames = floor(PLC4_TRANSIT_START_IN_MS / (frame_dms / 10.0));
+ plc_start_inFrames = floor(PLC4_TRANSIT_START_IN_MS / (frame_dms * 1.25));
}
- plc_end_inFrames = floor(PLC4_TRANSIT_END_IN_MS / (frame_dms / 10.0));
+ plc_end_inFrames = floor(PLC4_TRANSIT_END_IN_MS / (frame_dms * 1.25));
plc_duration_inFrames = plc_end_inFrames - plc_start_inFrames;
if (nbLostCmpt <= plc_start_inFrames)
diff --git a/lib_lc3plus/plc_main.c b/lib_lc3plus/plc_main.c
index 01fe7b237c11233b5d490cb83ad291b016da4560..507e78d128f64a4af3800a9881c471d1e74356d7 100644
--- a/lib_lc3plus/plc_main.c
+++ b/lib_lc3plus/plc_main.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -55,23 +55,29 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec*
{
switch(decoder->frame_dms)
{
- case 25:
- consecutiveLostThreshold = 16;
+#ifdef FIX_ADDITONAL_1p25_ISSUES
+ case LC3PLUS_FRAME_DURATION_1p25MS: consecutiveLostThreshold = 32;
+ thresh_tdc_cnt = THRESH_025_DMS_TDC_CNT;
+ thresh_ns_cnt = THRESH_025_DMS_NS_CNT;
+ thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT;
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS: consecutiveLostThreshold = 16;
thresh_tdc_cnt = THRESH_025_DMS_TDC_CNT;
thresh_ns_cnt = THRESH_025_DMS_NS_CNT;
thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT;
break;
- case 50: consecutiveLostThreshold = 8;
+ case LC3PLUS_FRAME_DURATION_5MS: consecutiveLostThreshold = 8;
thresh_tdc_cnt = THRESH_050_DMS_TDC_CNT;
thresh_ns_cnt = THRESH_050_DMS_NS_CNT;
thresh_tdc_ns_cnt = THRESH_050_DMS_TDC_NS_CNT;
break;
- case 75: consecutiveLostThreshold = 6;
+ case LC3PLUS_FRAME_DURATION_7p5MS: consecutiveLostThreshold = 6;
thresh_tdc_cnt = THRESH_075_DMS_TDC_CNT;
thresh_ns_cnt = THRESH_075_DMS_NS_CNT;
thresh_tdc_ns_cnt = THRESH_075_DMS_TDC_NS_CNT;
break;
- case 100: consecutiveLostThreshold = 4;
+ case LC3PLUS_FRAME_DURATION_10MS: consecutiveLostThreshold = 4;
thresh_tdc_cnt = THRESH_100_DMS_TDC_CNT;
thresh_ns_cnt = THRESH_100_DMS_NS_CNT;
thresh_tdc_ns_cnt = THRESH_100_DMS_TDC_NS_CNT;
@@ -98,7 +104,7 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec*
{
PlcAdvSetup->plc_fadeout_type = 0;
}
- if (h_DecSetup->rel_pitch_change > REL_PITCH_THRESH && hrmode == 1 && (decoder->frame_dms == 50 || decoder->frame_dms == 25) ){
+ if (h_DecSetup->rel_pitch_change > REL_PITCH_THRESH && hrmode == 1 && (decoder->frame_dms == LC3PLUS_FRAME_DURATION_5MS || decoder->frame_dms == LC3PLUS_FRAME_DURATION_2p5MS) ){
PlcAdvSetup->plc_fadeout_type = 2;
} else
if ( h_DecSetup->concealMethod != 2 ) {
@@ -120,9 +126,9 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec*
assert(decoder->fs_idx == floor(decoder->fs / 10000));
/* phaseECU supports only 10ms framing*/
- assert(PlcSetup->nbLostCmpt != 0 || decoder->frame_dms == 100);
+ assert(PlcSetup->nbLostCmpt != 0 || decoder->frame_dms == LC3PLUS_FRAME_DURATION_10MS);
- if (decoder->frame_dms != 100)
+ if (decoder->frame_dms != LC3PLUS_FRAME_DURATION_10MS)
{
/* muting, if frame size changed during phaseECU concealment */
memset(q_d_fl_c, 0, sizeof(LC3_FLOAT) * decoder->frame_length);
@@ -262,7 +268,7 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec*
}
yLen = MIN(decoder->frame_length, MAX_PLC_LMEM);
- if (PlcAdvSetup != NULL && (decoder->frame_dms == 100) && (hrmode == 0))
+ if (PlcAdvSetup != NULL && (decoder->frame_dms == LC3PLUS_FRAME_DURATION_10MS) && (hrmode == 0))
{
/* BASOP processPLCspec2shape_fx(prev_bfi, bfi, q_old_d_fx, yLen, plcAd->PhECU_oold_grp_shape_fx, plcAd->PhECU_old_grp_shape_fx);*/
plc_phEcu_processPLCspec2shape(prev_bfi_plc2, bfi, q_d_fl_c, yLen,
diff --git a/lib_lc3plus/plc_noise_substitution.c b/lib_lc3plus/plc_noise_substitution.c
index dc8e4d56fc6d5b7f2d9980ec7fd2c580d35aa3c8..89ae0a5bbe55e481f91811a2ec322d60797782c9 100644
--- a/lib_lc3plus/plc_noise_substitution.c
+++ b/lib_lc3plus/plc_noise_substitution.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_f0_refine_first.c b/lib_lc3plus/plc_phecu_f0_refine_first.c
index 7abb19813ca56889a2b025de577738de0f24d9f2..4752591bd6af3dabdfd57d2f0231e6ad74f9d772 100644
--- a/lib_lc3plus/plc_phecu_f0_refine_first.c
+++ b/lib_lc3plus/plc_phecu_f0_refine_first.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_fec_hq.c b/lib_lc3plus/plc_phecu_fec_hq.c
index bb7be94bf06ceea303394020cc999654054372eb..3d41a14057b0cf5067cd3de32db490fe169b162f 100644
--- a/lib_lc3plus/plc_phecu_fec_hq.c
+++ b/lib_lc3plus/plc_phecu_fec_hq.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_hq_ecu.c b/lib_lc3plus/plc_phecu_hq_ecu.c
index 8b2b981582dce5c62a3048e82145821ccabd6f7b..24da271224d6ba736bc9b0abcb6790cf24e2aa72 100644
--- a/lib_lc3plus/plc_phecu_hq_ecu.c
+++ b/lib_lc3plus/plc_phecu_hq_ecu.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_lf_peak_analysis.c b/lib_lc3plus/plc_phecu_lf_peak_analysis.c
index a53b6a4352ffd7d53cb0e48fbcddfe055333b78b..869efb9f3d324180b1ef80ee22004661c7673b49 100644
--- a/lib_lc3plus/plc_phecu_lf_peak_analysis.c
+++ b/lib_lc3plus/plc_phecu_lf_peak_analysis.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_rec_frame.c b/lib_lc3plus/plc_phecu_rec_frame.c
index 412c5205ca5a45a2d989a958021b16c8438fd605..cb693fadbbc968832b999c9eca50780865caed0c 100644
--- a/lib_lc3plus/plc_phecu_rec_frame.c
+++ b/lib_lc3plus/plc_phecu_rec_frame.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_setf0hz.c b/lib_lc3plus/plc_phecu_setf0hz.c
index c67f96d41028d366871894be7936f5e87fe52602..2f9752e50ee7494f18e6527ce1c7bb2f28f138ac 100644
--- a/lib_lc3plus/plc_phecu_setf0hz.c
+++ b/lib_lc3plus/plc_phecu_setf0hz.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_spec_ana.c b/lib_lc3plus/plc_phecu_spec_ana.c
index c8b46309ba6a36d452aa4b1b2781f23f8145dcfb..6e63844ca1f91b55ac27035241dbf28e95c932be 100644
--- a/lib_lc3plus/plc_phecu_spec_ana.c
+++ b/lib_lc3plus/plc_phecu_spec_ana.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -473,8 +473,8 @@ static void plc_phEcu_peak_locator_fxlike(const LC3_INT16 *inp, /* i: vector wit
{
tmp = sub(tmp, 1);
}
- num_pairs = tmp / 2; // shr(tmp, 1);
- n_tail_values = sub(tmp, num_pairs * 2); // shl(num_pairs, 1));
+ num_pairs = tmp / 2;
+ n_tail_values = sub(tmp, num_pairs * 2);
/* filter preliminary sign changes into sensitivity filtered sign changes */
diff --git a/lib_lc3plus/plc_phecu_subst_spec.c b/lib_lc3plus/plc_phecu_subst_spec.c
index 62a1d4434e8737437bdcbfa55727ca9e59e07006..b65d791d12afc20e3d5b64469389ae3bb959ac22 100644
--- a/lib_lc3plus/plc_phecu_subst_spec.c
+++ b/lib_lc3plus/plc_phecu_subst_spec.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -54,7 +54,7 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est,
corr_phase[i] = (LC3_FLOAT)2.0 * (LC3_FLOAT)M_PI_LC3PLUS * (f0est[i]/Lprot)*(LC3_FLOAT)t_adv;
}
- // EVOLVE PHASE -----------------
+ /* EVOLVE PHASE -----------------*/
one_peak_flag_mask = -1;
fs_idx = (LC3_INT16)LC3_FLOOR((LC3_FLOAT)Lprot / 160.0); /* aquire, fs_idx for 10 ms frame sizes */
diff --git a/lib_lc3plus/plc_phecu_tba_per_band_gain.c b/lib_lc3plus/plc_phecu_tba_per_band_gain.c
index 8bf33b88535a618bcf0a46a73f22533ef9f67172..3d5109f5c722ee4d9c9e4a2447dd20c8e842be53 100644
--- a/lib_lc3plus/plc_phecu_tba_per_band_gain.c
+++ b/lib_lc3plus/plc_phecu_tba_per_band_gain.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c
index ca58ade71e7e11e8f2ec7ba230455a157699a188..55e9f577935b2ebf208cf935b9416fb37039aa8a 100644
--- a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c
+++ b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c
index 0ea04fe1af96c1fae63a43f9c1f7ec04b3593893..ba41eaeaa575e637dd776cee60294483a810e513 100644
--- a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c
+++ b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c
index 52bee02583081e61971ef8f5cbfe8735228da4b8..bafa6c5f575bd2cd026e5e85e69fa88e580e4aed 100644
--- a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c
+++ b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_tdc.c b/lib_lc3plus/plc_tdc.c
index d789a9df29da9f9ffaccb67e18a1d0e9e0d0a2ca..a48371853dff3b52af0d1ef096a591b41a91a7f3 100644
--- a/lib_lc3plus/plc_tdc.c
+++ b/lib_lc3plus/plc_tdc.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -19,7 +19,7 @@
static LC3_INT16 TDC_random_short(LC3_INT16 *seed);
static LC3_FLOAT TDC_get_gainp(const LC3_FLOAT x[], const LC3_FLOAT y[], LC3_INT32 n);
-static LC3_FLOAT TDC_get_gainc(const LC3_FLOAT x[], const LC3_FLOAT y[], const LC3_FLOAT *gain_p, const LC3_INT32 n, const LC3_INT32 frame_dms);
+static LC3_FLOAT TDC_get_gainc(const LC3_FLOAT x[], const LC3_FLOAT y[], const LC3_FLOAT *gain_p, const LC3_INT32 n, const LC3PLUS_FrameDuration frame_dms);
static void TDC_LPC_synthesis(const LC3_FLOAT a[], LC3_FLOAT x[], LC3_FLOAT y[], LC3_INT32 l, const LC3_FLOAT mem[], LC3_INT32 lpcorder, LC3_FLOAT *buf);
static void TDC_LPC_residu(const LC3_FLOAT *a, LC3_FLOAT *x, LC3_FLOAT *y, LC3_INT32 l, LC3_INT32 lpcorder);
static void TDC_highPassFiltering(const LC3_INT32 L_buffer, LC3_FLOAT exc2[], const LC3_FLOAT hp_filt[], const LC3_INT32 l_fir_fer);
@@ -32,7 +32,23 @@ const LC3_FLOAT TDC_high_32_harm[TDC_L_FIR_HP] = {-0.0053f, -0.0037f, -0.0140f,
static void TDC_levinson(LC3_FLOAT *acf, LC3_INT32 len, LC3_FLOAT *out);
static void TDC_copyFLOAT(const LC3_FLOAT * X, LC3_FLOAT * Z, LC3_INT32 n);
static LC3_FLOAT TDC_dotFLOAT(const LC3_FLOAT * X, const LC3_FLOAT * Y, LC3_INT32 n);
-static LC3_FLOAT type_2_alpha_long(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms);
+static LC3_FLOAT type_2_alpha_long(LC3_INT32 nbLostFramesInRow, LC3PLUS_FrameDuration frame_dms);
+#ifdef FIX_TDC_BURST_ERROR
+const LC3_INT32 beforeNextIncArray[5][8] = {
+ { 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 0, 0, 0, 1, 0, 0, 0, 1 },
+ { 0, 1, 0, 1, 0, 1, 0, 1 },
+ { 0, 1, 1, 1, 0, 1, 1, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 1 }
+};
+const LC3_INT32 nextIncArray[5][8] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 0, 0, 0, 1, 0, 0, 0 },
+ { 1, 0, 1, 0, 1, 0, 1, 0 },
+ { 1, 0, 1, 1, 1, 0, 1, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 1 }
+};
+#else
const LC3_INT32 beforeNextIncArray[4][4] = {{0,0,0,1},
{0,1,0,1},
{0,1,1,1},
@@ -41,7 +57,7 @@ const LC3_INT32 nextIncArray[4][4] = {{1,0,0,0},
{1,0,1,0},
{1,0,1,1},
{1,1,1,1}};
-
+#endif
void processTdcApply_fl(const LC3_INT32 pitch_int,
const LC3_FLOAT *preemphFac,
const LC3_FLOAT* A,
@@ -49,7 +65,7 @@ void processTdcApply_fl(const LC3_INT32 pitch_int,
const LC3_FLOAT* pcmbufHist,
const LC3_INT32 max_len_pcm_plc,
const LC3_INT32 N,
- const LC3_INT32 frame_dms,
+ const LC3PLUS_FrameDuration frame_dms,
const LC3_INT32 SampRate,
const LC3_INT32 nbLostFramesInRow,
const LC3_INT32 overlap,
@@ -62,7 +78,7 @@ void processTdcApply_fl(const LC3_INT32 pitch_int,
LC3_FLOAT* alpha,
LC3_FLOAT* synth
, LC3_UINT8 plc_fadeout_type
- , LC3_FLOAT* alpha_type_2_table
+ ,LC3_FLOAT* alpha_type_2_table
)
{
LC3_FLOAT step, step_n;
@@ -87,9 +103,18 @@ void processTdcApply_fl(const LC3_INT32 pitch_int,
/* len of synthesized signal */
len = N + overlap;
- nbLostCmpt_loc = floor(frame_dms/100.0 * (nbLostFramesInRow - 1) + 1);
- frame_dms_idx = frame_dms / 25 - 1; /* 0,1,2,3 */
- nbLostFramesInRow_mod = (nbLostFramesInRow - 1) % 4;
+ nbLostCmpt_loc = floor(frame_dms*1.25*10/100.0 * (nbLostFramesInRow - 1) + 1);
+
+#ifdef FIX_TDC_BURST_ERROR
+ if (frame_dms == 1)
+ frame_dms_idx = 0;
+ else
+ frame_dms_idx = frame_dms / 2;
+ nbLostFramesInRow_mod = ( nbLostFramesInRow - 1 ) % 8;
+#else
+ frame_dms_idx = frame_dms*1.25*10 / 25 - 1; /* 0,1,2,3 */
+ nbLostFramesInRow_mod = (nbLostFramesInRow - 1) % 4;
+#endif
beforeNextInc = beforeNextIncArray[frame_dms_idx][nbLostFramesInRow_mod];
nextInc = nextIncArray [frame_dms_idx][nbLostFramesInRow_mod];
@@ -245,10 +270,14 @@ void processTdcApply_fl(const LC3_INT32 pitch_int,
{
switch (frame_dms)
{
- case 25: *alpha *= PLC34_ATTEN_FAC_025; break;
- case 50: *alpha *= PLC34_ATTEN_FAC_025; break;
- case 75: *alpha *= PLC34_ATTEN_FAC_075; break;
- case 100: *alpha *= PLC34_ATTEN_FAC_100; break;
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS: *alpha *= PLC34_ATTEN_FAC_0125; break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS: *alpha *= PLC34_ATTEN_FAC_025; break;
+ case LC3PLUS_FRAME_DURATION_5MS: *alpha *= PLC34_ATTEN_FAC_025; break;
+ case LC3PLUS_FRAME_DURATION_7p5MS: *alpha *= PLC34_ATTEN_FAC_075; break;
+ case LC3PLUS_FRAME_DURATION_10MS: *alpha *= PLC34_ATTEN_FAC_100; break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED: assert(0);
}
}
@@ -469,14 +498,14 @@ void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT
}
}
-void processTdcLpcEstimation_fl(LC3_FLOAT *r, LC3_INT32 fs_idx, LC3_INT32 len, LC3_FLOAT *A, LC3_INT32 frame_dms)
+void processTdcLpcEstimation_fl(LC3_FLOAT *r, LC3_INT32 fs_idx, LC3_INT32 len, LC3_FLOAT *A, LC3PLUS_FrameDuration frame_dms)
{
LC3_INT32 i;
const LC3_FLOAT *lpc_array;
lpc_array = plc_tdc_lpc_all[fs_idx];
- if (fs_idx == 0 && frame_dms == 25)
+ if (fs_idx == 0 && frame_dms == LC3PLUS_FRAME_DURATION_2p5MS)
{
lpc_array = plc_tdc_lpc_8_25ms;
}
@@ -532,7 +561,7 @@ static LC3_FLOAT TDC_get_gainc( /* output: gain of code
const LC3_FLOAT y[], /* input : shifted input signal */
const LC3_FLOAT *gain_p, /* input : gain of pitch */
const LC3_INT32 n, /* input : vector length */
- const LC3_INT32 frame_dms /* input : frame length in dms */
+ const LC3PLUS_FrameDuration frame_dms /* input : frame length in dms */
)
{
LC3_FLOAT gain_c;
@@ -546,7 +575,7 @@ static LC3_FLOAT TDC_get_gainc( /* output: gain of code
gain_c += ( x[-i] - *gain_p * y[-i] ) * ( x[-i] - *gain_p * y[-i] );
}
- if (frame_dms < 100)
+ if (frame_dms < LC3PLUS_FRAME_DURATION_10MS)
{
for (i = 0; i < n; i++)
{
@@ -777,24 +806,24 @@ static void TDC_levinson(LC3_FLOAT *acf, LC3_INT32 len, LC3_FLOAT *out)
}
}
-static LC3_FLOAT type_2_alpha_long(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms)
+static LC3_FLOAT type_2_alpha_long(LC3_INT32 nbLostFramesInRow, LC3PLUS_FrameDuration frame_dms)
{
- if (nbLostFramesInRow <= 3*100.0/frame_dms){
- return LC3_POW(0.95,(nbLostFramesInRow + (100.0/frame_dms) - 1) * frame_dms/100.0);
+ if (nbLostFramesInRow <= 3*100.0/(frame_dms*1.25*10)){
+ return LC3_POW(0.95,(nbLostFramesInRow + (100.0/(frame_dms*1.25*10)) - 1) * (frame_dms*1.25*10)/100.0);
}
else {
- LC3_INT32 n_shift = (nbLostFramesInRow - 3*100.0/frame_dms) * 50/frame_dms;
- return LC3_POW(0.7,(n_shift + 100.0/frame_dms - 1) * frame_dms/100.0);
+ LC3_INT32 n_shift = (nbLostFramesInRow - 3*100.0/(frame_dms*1.25*10)) * 50/(frame_dms*1.25*10);
+ return LC3_POW(0.7,(n_shift + 100.0/(frame_dms*1.25*10) - 1) * (frame_dms*1.25*10)/100.0);
}
}
-LC3_FLOAT type_2_fadeout(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms)
+LC3_FLOAT type_2_fadeout(LC3_INT32 nbLostFramesInRow, LC3PLUS_FrameDuration frame_dms)
{
- LC3_FLOAT selector = PLC_FADEOUT_TYPE_2_SELECTOR * 2 * 100/frame_dms;
+ LC3_FLOAT selector = PLC_FADEOUT_TYPE_2_SELECTOR * 2 * 100/(frame_dms*1.25*10);
if (selector >= nbLostFramesInRow){
return type_2_alpha_long(nbLostFramesInRow, frame_dms);
}
else {
- return LC3_POW(0.5,(nbLostFramesInRow + (100.0/frame_dms) - 1) * frame_dms/100.0);
+ return LC3_POW(0.5,(nbLostFramesInRow + (100.0/(frame_dms*1.25*10)) - 1) * (frame_dms*1.25*10)/100.0);
}
}
diff --git a/lib_lc3plus/plc_tdc_tdac.c b/lib_lc3plus/plc_tdc_tdac.c
index 5aa4248bdff0d249c41e1f9f2677a37c41ebc9d9..bcb0e1770fdb9529610ce1772f907b6578d1e4a8 100644
--- a/lib_lc3plus/plc_tdc_tdac.c
+++ b/lib_lc3plus/plc_tdc_tdac.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/plc_update.c b/lib_lc3plus/plc_update.c
index f45afb40624dcdc007351bdd049de499bdb42aba..1f331c00a46298b52b3ddb85c45dbb2bdfc15bca 100644
--- a/lib_lc3plus/plc_update.c
+++ b/lib_lc3plus/plc_update.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/quantize_spec.c b/lib_lc3plus/quantize_spec.c
index 568dbe1fe1492a2bd14a7ce7abe58c0f8cb108cd..89aa6b9d2ca60a48f9036d0f296bfc3acd12c7c3 100644
--- a/lib_lc3plus/quantize_spec.c
+++ b/lib_lc3plus/quantize_spec.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -231,11 +231,11 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT
c = (c & 15) * 16 + t;
}
- *nbits = (bits + 2047) >> 11; // Exactly same as ceil((LC3_FLOAT)*nbits / 2048.0);
+ *nbits = (bits + 2047) >> 11; /* same as ceil((LC3_FLOAT)*nbits / 2048.0);*/
if (mode >= 0)
{
- *nbits2 = (bits2 + 2047) >> 11; //ceil((LC3_FLOAT)*nbits2 / 2048.0);
+ *nbits2 = (bits2 + 2047) >> 11; /* ceil((LC3_FLOAT)*nbits2 / 2048.0); */
}
else
{
diff --git a/lib_lc3plus/reorder_bitstream.c b/lib_lc3plus/reorder_bitstream.c
index 3ab549d04b3a221233c7a2bc93495cad3725edc9..48254976692f35dca24bc8f7865e79fab05c81ca 100644
--- a/lib_lc3plus/reorder_bitstream.c
+++ b/lib_lc3plus/reorder_bitstream.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/resamp12k8.c b/lib_lc3plus/resamp12k8.c
index 0909b67b9b5ff83854ca9726073502622b5ead2c..a5847c5e530fe5a7e4bac8433bc1eaf34507d2db 100644
--- a/lib_lc3plus/resamp12k8.c
+++ b/lib_lc3plus/resamp12k8.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -12,11 +12,11 @@
#include "functions.h"
void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[],
- LC3_INT mem_out_len, LC3_FLOAT y[], LC3_INT* y_len, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT fs)
+ LC3_INT mem_out_len, LC3_FLOAT y[], LC3_INT* y_len, LC3_INT fs_idx, LC3PLUS_FrameDuration frame_dms, LC3_INT fs)
{
- LC3_INT len_12k8, N12k8, i, k;
+ LC3_INT len_12k8 = 0, N12k8, i, k;
LC3_FLOAT mac, bufdown[128], buf[120 + MAX_LEN];
LC3_INT32 index_int, index_frac, resamp_upfac, resamp_delay, resamp_off_int, resamp_off_frac;
LC3_FLOAT u_11, u_21, u_1, u_2;
@@ -25,18 +25,25 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3
switch (frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ len_12k8 = LEN_12K8 / 8;
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
len_12k8 = LEN_12K8 / 4;
break;
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
len_12k8 = LEN_12K8 / 2;
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
len_12k8 = (LEN_12K8 / 4) * 3;
break;
- case 100:
+ case LC3PLUS_FRAME_DURATION_10MS:
len_12k8 = LEN_12K8;
break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
*y_len = len_12k8;
diff --git a/lib_lc3plus/residual_coding.c b/lib_lc3plus/residual_coding.c
index 282b7655e7224a021e4727b93291cf1e1dd1be50..1e788723f763f355439e0478df115c99946dea5e 100644
--- a/lib_lc3plus/residual_coding.c
+++ b/lib_lc3plus/residual_coding.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,13 +11,15 @@
#include "wmc_auto.h"
#include "functions.h"
-void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t* resBits, LC3_INT* numResBits
- , LC3_INT hrmode
+void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t* resBits, LC3_INT* numResBits, LC3_INT hrmode
+#ifdef ENABLE_12p5_DMS_MODE
+ , LC3PLUS_FrameDuration frame_dms
+#endif
)
{
LC3_INT n = 0, m = 0, k = 0;
LC3_INT iter=0;
- LC3_FLOAT offset;
+ LC3_FLOAT offset[3];
LC3_INT iter_max = 1;
LC3_INT nz_idx[MAX_LEN];
LC3_INT N_nz = 0, idx = 0;
@@ -33,12 +35,23 @@ void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_I
assert(m <= MAX_RESBITS);
- offset = .25;
+ offset[2] = .5;
if (hrmode)
{
iter_max = EXT_RES_ITER_MAX;
-
}
+#ifdef ENABLE_12p5_DMS_MODE
+ else if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ iter_max = 3;
+ offset[2] = .375;
+ }
+#endif
+
+ /* init offset */
+ offset[0] = offset[2] / 2.;
+ offset[1] = (1.-offset[2]) / 2.;
+
for (k = 0; k < L_spec; k ++)
{
if (xq[k])
@@ -56,12 +69,12 @@ void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_I
if (x[idx] >= (LC3_FLOAT)xq[idx] * gain)
{
resBits[n >> 3] |= 1 << (n & 7);
- x[idx] -= gain * offset;
+ x[idx] -= gain * offset[x[idx] > 0];
}
else
{
resBits[n >> 3] &= ~(1 << (n & 7));
- x[idx] += gain * offset;
+ x[idx] += gain * offset[x[idx] < 0];
}
n++;
@@ -69,7 +82,8 @@ void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_I
k++;
}
iter ++;
- offset *= .5;
+ offset[0] *= .5;
+ offset[1] *= .5;
}
*numResBits = n;
diff --git a/lib_lc3plus/residual_decoding.c b/lib_lc3plus/residual_decoding.c
index 9970c094ba7909e664e663491485f2e24331a1d8..dff8bd64d7eb412e067ea63f023d515cebc5f1b4 100644
--- a/lib_lc3plus/residual_decoding.c
+++ b/lib_lc3plus/residual_decoding.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,8 +11,10 @@
#include "wmc_auto.h"
#include "functions.h"
-void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits
- , LC3_INT hrmode
+void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits, LC3_INT hrmode
+#ifdef ENABLE_12p5_DMS_MODE
+ , LC3PLUS_FrameDuration frame_dms
+#endif
)
{
LC3_INT k = 0, n = 0;
@@ -33,9 +35,14 @@ void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec
offset1 = 0.1875;
offset2 = 0.3125;
}
-
- if (hrmode)
+
+#ifdef ENABLE_12p5_DMS_MODE
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
{
+ iter_max = 3;
+ }
+#endif
+
/* enumerat non-zero coefficients */
for (k = 0; k < L_spec; k ++)
{
@@ -44,6 +51,10 @@ void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec
nz_idx[N_nz ++] = k;
}
}
+
+ if (hrmode)
+ {
+
/* apply residual corrections */
while (n < resQBits && iter < iter_max)
{
@@ -71,26 +82,35 @@ void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec
}
else
{
- while (k < L_spec && n < resQBits) {
- if (x[k] != 0) {
+ UNUSED(offset);
+
+ while (n < resQBits && iter < iter_max) {
+ for (k = 0; k < N_nz; k ++)
+ {
+ idx = nz_idx[k];
+
if ((prm[n >> 3] & 1 << (n & 7)) == 0)
{
- if (x[k] > 0) {
- x[k] -= offset1;
+ if (x[idx] > 0) {
+ x[idx] -= offset1;
} else {
- x[k] -= offset2;
+ x[idx] -= offset2;
}
} else {
- if (x[k] > 0) {
- x[k] += offset2;
+ if (x[idx] > 0) {
+ x[idx] += offset2;
} else {
- x[k] += offset1;
+ x[idx] += offset1;
}
}
- n++;
+ if (++n >= resQBits)
+ {
+ break;
+ }
}
-
- k++;
+ offset1 *= 0.5;
+ offset2 *= 0.5;
+ iter ++;
}
}
*bitsRead = n;
diff --git a/lib_lc3plus/setup_com_lc3plus.c b/lib_lc3plus/setup_com_lc3plus.c
new file mode 100644
index 0000000000000000000000000000000000000000..055b6a0047f7a769857550a7e4fab9ad5a4c3022
--- /dev/null
+++ b/lib_lc3plus/setup_com_lc3plus.c
@@ -0,0 +1,55 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.6.1 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "options.h"
+#include "wmc_auto.h"
+#include "functions.h"
+
+#ifdef FIX_BOTH_1p25_WB_GLOBGAINOFFSET_NONBE
+/* tilt factor in gainOffset quantized and adjusted for low Fs and 1p25ms framing */
+LC3_INT16 calc_GGainOffset_1p25(LC3_INT16 total_bits, LC3_INT16 fs_idx)
+{
+ LC3_INT16 gain_off_tilt_1p25_Q19[6] = { 20480, 17408, 17476, 13107, 10486, 8738 }; /* vector of 1p25 tilts for NB to UB */
+ /* Corresponding FLT = gain_off_tilt_1p25 = {0.039062500000000 0.033203125000000 0.033333333333333 0.025000000000000 0.020000000000000 0.016666666666667 }*/
+
+
+ LC3_INT16 tmp1 = (LC3_INT16)( ( ((LC3_INT32)total_bits)*((LC3_INT32)gain_off_tilt_1p25_Q19[fs_idx]) ) >> (3 + 16) ); /*no rounding on purpose */
+ LC3_INT16 tmp2 = 105 + 5 * (fs_idx + 1);
+
+ tmp2 = -(MIN(115, tmp1) + tmp2);
+
+#ifdef FIX_BOTH_1p25_WB_GLOBGAINOFFSET_LOWLIM_NONBE
+ if (fs_idx <= 1)
+ { /* only NB and WB additionally limited to -135 */
+ tmp2 = MAX(tmp2, FIX_BOTH_1p25_WB_GLOBGAINOFFSET_LOWLIM_NONBE);
+ }
+#endif
+
+ return tmp2;
+}
+#endif
+
+LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len)
+{
+ LC3_FLOAT max;
+ LC3_INT32 i;
+
+ max = LC3_FABS(in[0]);
+
+ for (i = 0; i < len; i++)
+ {
+ if (LC3_FABS(in[i]) > LC3_FABS(max))
+ {
+ max = LC3_FABS(in[i]);
+ }
+ }
+
+ return max;
+}
+
diff --git a/lib_lc3plus/setup_dec_lc3.c b/lib_lc3plus/setup_dec_lc3plus.c
similarity index 76%
rename from lib_lc3plus/setup_dec_lc3.c
rename to lib_lc3plus/setup_dec_lc3plus.c
index 7bdbf0523da2e9867aa93f84029a261739b6384c..67a86bb027eb4a3076f539305382696034b69da4 100644
--- a/lib_lc3plus/setup_dec_lc3.c
+++ b/lib_lc3plus/setup_dec_lc3plus.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -9,7 +9,7 @@
#include "options.h"
#include "wmc_auto.h"
-#include "setup_dec_lc3.h"
+#include "setup_dec_lc3plus.h"
#include "functions.h"
#include
#include
@@ -34,7 +34,7 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels)
HANDLE_IIS_FFT handle_fft_phaseecu;
HANDLE_IIS_FFT handle_ifft_phaseecu;
LC3_FLOAT *q_old_res;
-
+
LC3_INT32 * plc_longterm_advc_tdc = NULL, *plc_longterm_advc_ns = NULL;
LC3_INT16 longterm_analysis_counter_max = 0, longterm_analysis_counter_max_bytebuffer = 0;
@@ -51,16 +51,16 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels)
PhECU_xfp = balloc(decoder, &size, sizeof(LC3_FLOAT) *(frame_len * 16 / 10));
PhECU_X_sav_m = balloc(decoder, &size, sizeof(Complex) *(((frame_len * 16 / 10) / 2) + 1));/*MAX_PLC_LMSPEC*/
PhECU_plocs = balloc(decoder, &size, sizeof(LC3_INT32) * (((frame_len * 16 / 10) / 4) + 1 + 1)); /* BASOP Word16 *PhECU_plocs; */
-
+
handle_fft_phaseecu = balloc(decoder, &size, sizeof(IIS_FFT) * 1);
handle_ifft_phaseecu = balloc(decoder, &size, sizeof(IIS_FFT) * 1);
PhECU_f0est = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((frame_len * 16 / 10) / 4) + 1)); /*BASOP Word32 *PhECU_f0est;*/
PhECU_mag_chg_1st = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_mag_chg_1st[MAX_LGW];*/
PhECU_Xavg = balloc(decoder, &size, sizeof(LC3_FLOAT) * MAX_LGW); /* BASOP Word16 PhECU_Xavg[MAX_LGW] ; */
-
+
sine_table1_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1));
sine_table2_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1));
-
+
longterm_analysis_counter_max = plc_fadeout_param_maxlen[0];
longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[0];
@@ -71,6 +71,16 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels)
if (decoder) {
decoder->channel_setup[ch] = setup;
+#ifdef CR9_C_ADD_1p25MS
+ setup->ltpf_mem_continuation = 0;
+#ifdef FIX_TX_RX_STRUCT_STEREO
+ setup->ltpf_rx_status[0] = 0;
+ setup->ltpf_rx_status[1] = 0;
+#endif
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ setup->ltpfinfo_frame_cntr = -32768;
+#endif
+#endif
setup->PlcAdvSetup = PlcAdvSetup;
@@ -86,16 +96,16 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels)
setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Xavg = PhECU_Xavg;
setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu = handle_fft_phaseecu;
setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu = handle_ifft_phaseecu;
-
+
setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu->sine_table = sine_table1_phecu;
setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu->sine_table = sine_table2_phecu;
-
+
setup->PlcAdvSetup->longterm_analysis_counter_max = longterm_analysis_counter_max;
setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = longterm_analysis_counter_max_bytebuffer;
-
+
setup->PlcAdvSetup->plc_longterm_advc_tdc = plc_longterm_advc_tdc;
setup->PlcAdvSetup->plc_longterm_advc_ns = plc_longterm_advc_ns;
-
+
setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (CODEC_FS(samplerate) * 16) / 1000;
real_fft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu));
real_ifft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu));
@@ -117,14 +127,14 @@ LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, L
decoder->fs_out = samplerate;
decoder->fs_idx = FS2FS_IDX(decoder->fs);
decoder->plcMeth = plc_mode;
-
+
decoder->hrmode = hrmode != 0;
decoder->channels = channels;
- decoder->frame_ms = 10;
- decoder->frame_dms = 100;
+ decoder->frame_ms = LC3PLUS_FRAME_DURATION_10MS;
+ decoder->frame_dms = LC3PLUS_FRAME_DURATION_10MS;
decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx];
-
+
if (decoder->fs == 8000) {
decoder->tilt = 14;
} else if (decoder->fs == 16000) {
@@ -143,14 +153,14 @@ LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, L
set_dec_frame_params(decoder);
lc3plus_dec_set_ep_enabled(decoder, 0);
-
+
return LC3PLUS_OK;
}
/* set frame config params */
void set_dec_frame_params(LC3PLUS_Dec* decoder)
{
- int ch = 0;
+ int ch = 0, idx = 0;
int n;
if (decoder->fs_idx == 5)
@@ -168,34 +178,66 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
decoder->yLen = MIN(MAX_BW, decoder->frame_length);
}
+#ifndef FIX_TX_RX_STRUCT_STEREO
+ decoder->ltpf_rx_status[0] = 0;
+ decoder->ltpf_rx_status[1] = 0;
+#endif
+
decoder->bands_number = 64;
- if (decoder->frame_ms == 2.5)
+#ifdef CR9_C_ADD_1p25MS
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ decoder->frame_length = decoder->frame_length >> 3;
+ decoder->yLen /= 8;
+
+ if (decoder->hrmode)
+ {
+ assert(0);
+ }
+ else
+ {
+ decoder->bands_number = bands_number_1_25ms[decoder->fs_idx];
+ }
+
+ decoder->bands_offset = ACC_COEFF_PER_BAND_1_25ms[decoder->fs_idx];
+ decoder->BW_cutoff_bits = 0;
+ decoder->cutoffBins = BW_cutoff_bin_all_1_25ms;
+
+ decoder->imdct_win = MDCT_WINS_1_25ms[decoder->hrmode][decoder->fs_idx];
+ decoder->imdct_laZeros = MDCT_la_zeroes_1_25ms[decoder->fs_idx];
+ decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_1_25ms[decoder->fs_idx];
+
+ decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_1_25ms[decoder->fs_idx];
+ decoder->n_bandsPLC = decoder->frame_length;
+ }
+#endif
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS)
{
decoder->frame_length = decoder->frame_length >> 2;
decoder->yLen /= 4;
if (decoder->hrmode)
{
decoder->bands_number = bands_number_2_5ms_HR[decoder->fs_idx];
- }
+ }
else
{
decoder->bands_number = bands_number_2_5ms[decoder->fs_idx];
}
}
- if (decoder->frame_ms == 5)
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS)
{
decoder->frame_length = decoder->frame_length >> 1;
decoder->yLen /= 2;
decoder->bands_number = bands_number_5ms[decoder->fs_idx];
}
- if (decoder->frame_ms == 7.5)
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS)
{
decoder->frame_length = (decoder->frame_length >> 2) * 3;
- decoder->yLen = (decoder->yLen / 4) * 3;
+ decoder->yLen = (decoder->yLen / 4) * 3;
if (decoder->hrmode)
{
decoder->bands_number = bands_number_7_5ms_HR[decoder->fs_idx];
- }
+ }
else
{
decoder->bands_number = bands_number_7_5ms[decoder->fs_idx];
@@ -206,12 +248,18 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
{
decoder->BW_cutoff_bits = 0;
}
+#ifdef CR9_C_ADD_1p25MS
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ decoder->BW_cutoff_bits = 0;
+ }
+#endif
else
{
decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx];
}
- if (decoder->frame_ms == 10)
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_10MS)
{
if (decoder->hrmode)
{
@@ -223,7 +271,7 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
}
decoder->cutoffBins = BW_cutoff_bin_all;
}
- else if (decoder->frame_ms == 2.5)
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS)
{
if (decoder->hrmode)
{
@@ -235,7 +283,7 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
}
decoder->cutoffBins = BW_cutoff_bin_all_2_5ms;
}
- else if (decoder->frame_ms == 5)
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS)
{
if (decoder->hrmode)
{
@@ -247,7 +295,7 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
}
decoder->cutoffBins = BW_cutoff_bin_all_5ms;
}
- else if (decoder->frame_ms == 7.5)
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS)
{
if (decoder->hrmode)
{
@@ -259,14 +307,14 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
}
decoder->cutoffBins = BW_cutoff_bin_all_7_5ms;
}
-
+
decoder->n_bandsPLC = MIN(decoder->frame_length, 80);
-
- if (decoder->frame_ms == 10)
+
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_10MS)
{
decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC[decoder->fs_idx];
}
- else if (decoder->frame_ms == 5)
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS)
{
decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_5ms[decoder->fs_idx];
@@ -275,7 +323,7 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
decoder->n_bandsPLC = 40;
}
}
- else if (decoder->frame_ms == 2.5)
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS)
{
decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_2_5ms[decoder->fs_idx];
@@ -284,38 +332,56 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
decoder->n_bandsPLC = 60;
}
}
- else if (decoder->frame_ms == 7.5)
+#ifdef CR9_C_ADD_1p25MS
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_1_25ms[decoder->fs_idx];
+
+ if (decoder->fs == 48000)
+ {
+ decoder->n_bandsPLC = 60;
+ }
+ }
+#endif
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS)
{
decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_7_5ms[decoder->fs_idx];
-
+
if (decoder->fs != 32000 && decoder->fs != 96000)
{
decoder->n_bandsPLC = 60;
}
}
-
+
assert(decoder->bands_offsetPLC);
- if (decoder->frame_ms == 10) {
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_10MS) {
decoder->imdct_win = MDCT_WINS_10ms[decoder->hrmode][decoder->fs_idx];
decoder->imdct_laZeros = MDCT_la_zeroes[decoder->fs_idx];
decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_10ms[decoder->fs_idx];
}
- else if (decoder->frame_ms == 2.5) {
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS) {
decoder->imdct_win = MDCT_WINS_2_5ms[decoder->hrmode][decoder->fs_idx];
decoder->imdct_laZeros = MDCT_la_zeroes_2_5ms[decoder->fs_idx];
decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_2_5ms[decoder->fs_idx];
}
- else if (decoder->frame_ms == 5) {
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS) {
decoder->imdct_win = MDCT_WINS_5ms[decoder->hrmode][decoder->fs_idx];
decoder->imdct_laZeros = MDCT_la_zeroes_5ms[decoder->fs_idx];
decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_5ms[decoder->fs_idx];
}
- else if (decoder->frame_ms == 7.5) {
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS) {
decoder->imdct_win = MDCT_WINS_7_5ms[decoder->hrmode][decoder->fs_idx];
decoder->imdct_laZeros = MDCT_la_zeroes_7_5ms[decoder->fs_idx];
decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_7_5ms[decoder->fs_idx];
}
+#ifdef CR9_C_ADD_1p25MS
+ else if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ decoder->imdct_win = MDCT_WINS_1_25ms[decoder->hrmode][decoder->fs_idx];
+ decoder->imdct_laZeros = MDCT_la_zeroes_1_25ms[decoder->fs_idx];
+ decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_1_25ms[decoder->fs_idx];
+ }
+#endif
decoder->la_zeroes = decoder->imdct_laZeros;
@@ -323,9 +389,9 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
for (ch = 0; ch < decoder->channels; ch++) {
DecSetup* setup = decoder->channel_setup[ch];
-
+
setup->ltpf_mem_beta_idx = -1;
-
+
setup->statePC.seed = 24607;
if (decoder) {
@@ -336,7 +402,7 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
} else {
dct4_init(&setup->dct4structImdct, decoder->frame_length);
}
-
+
setup->PlcNsSetup.cum_alpha = 1;
setup->PlcNsSetup.seed = 24607;
setup->alpha = 1;
@@ -344,14 +410,14 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
{
LC3_INT32 pitch_max = 0, pitch_ana_len = 0, tdc_synt_len = 0;
pitch_max = ceil(228.0 * (LC3_FLOAT) decoder->fs / 12800.0);
- pitch_ana_len = pitch_max + decoder->frame_length * (LC3_FLOAT) 100 / decoder->frame_dms;
+ pitch_ana_len = pitch_max + decoder->frame_length * (LC3_FLOAT) 100 / (decoder->frame_dms * 1.25 * 10);
tdc_synt_len = 16 + 1 + pitch_max + ceil(decoder->frame_length / 2);
setup->PlcAdvSetup->max_len_pcm_plc = MAX(pitch_ana_len, tdc_synt_len);
setup->PlcAdvSetup->PlcTdcSetup.preemphFac = plc_preemph_fac[decoder->fs_idx];
setup->PlcAdvSetup->PlcTdcSetup.seed = 24607;
setup->PlcAdvSetup->PlcTdcSetup.lpcorder = 16;
- if (decoder->fs_idx == 0 && decoder->frame_dms == 25)
+ if ((decoder->fs_idx == 0 || decoder->frame_length <= 20) && decoder->frame_dms <= LC3PLUS_FRAME_DURATION_2p5MS)
{
setup->PlcAdvSetup->PlcTdcSetup.lpcorder = 8;
}
@@ -360,11 +426,12 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
setup->PlcAdvSetup->cum_fading_fast = 1;
setup->PlcAdvSetup->cum_fading_slow = 1;
setup->PlcAdvSetup->cum_fflcAtten = 1;
-
- setup->PlcAdvSetup->longterm_analysis_counter_max = plc_fadeout_param_maxlen[(decoder->frame_dms / 25) - 1];
- setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[(decoder->frame_dms / 25) - 1];
- if (decoder->fs_idx <= 4 && decoder->frame_dms == 100)
+ idx = (decoder->frame_dms * 1.25 * 10 / 25) - 1;
+ setup->PlcAdvSetup->longterm_analysis_counter_max = plc_fadeout_param_maxlen[idx];
+ setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[idx];
+
+ if (decoder->fs_idx <= 4 && decoder->frame_dms == LC3PLUS_FRAME_DURATION_10MS)
{
setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (decoder->fs * 16) / 1000; /* 16 ms of samples at fs*/
@@ -386,7 +453,7 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_beta_mute = (16384.0/32768.0);
setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_seed = 21845;
- assert(decoder->frame_dms == 100);
+ assert(decoder->frame_dms == LC3PLUS_FRAME_DURATION_10MS);
setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_LDWIN_OLAP = (decoder->frame_length / 4 ); /* 2.5 ms for regular 10 ms MDCT */
setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_t_adv = (
@@ -400,9 +467,9 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder)
}
}
}
- for (n=0; n < LC3_ROUND(PLC_FADEOUT_TYPE_1_IN_MS*10/decoder->frame_dms);n++){
+ for (n=0; n < LC3_ROUND(PLC_FADEOUT_TYPE_1_IN_MS*10/(decoder->frame_dms*1.25*10));n++){
decoder->alpha_type_2_table[n] = type_2_fadeout(n, decoder->frame_dms);
- }
+ }
}
LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes)
@@ -414,19 +481,26 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes)
{
switch (decoder->frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ assert(0);
+ maxBytes = 210;
+ minBytes = MIN_NBYTES;
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
maxBytes = 210;
minBytes = MIN_NBYTES;
break;
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
maxBytes = 375;
minBytes = MIN_NBYTES;
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
maxBytes = 625;
minBytes = MIN_NBYTES;
- break;
- case 100:
+ break;
+ case LC3PLUS_FRAME_DURATION_10MS:
maxBytes = 625;
minBytes = MIN_NBYTES;
break;
@@ -437,7 +511,7 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes)
else
{
minBytes = MIN_NBYTES;
- maxBytes = MAX_NBYTES_100; /* for backward compatibility, MAX_NBYTES_100 is used for all frame lengths */
+ maxBytes = MAX_NBYTES_100; /* for backward compatibility, MAX_NBYTES_100 is used for all frame lengths */
}
channel_bytes = nBytes;
@@ -448,12 +522,25 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes)
{
return LC3PLUS_NUMBYTES_ERROR;
}
-
+
setup->targetBytes = channel_bytes;
setup->total_bits = setup->targetBytes << 3;
setup->enable_lpc_weighting = (setup->total_bits < 480);
+
+#ifdef FIX_BOTH_1p25_WB_GLOBGAINOFFSET_NONBE
+ if (decoder->frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ setup->quantizedGainOff = calc_GGainOffset_1p25(setup->total_bits, decoder->fs_idx); /* enc/dec common function */
+ }
+ else
+ {
+ setup->quantizedGainOff =
+ -(MIN(115, setup->total_bits / (10 * (decoder->fs_idx + 1))) + 105 + 5 * (decoder->fs_idx + 1));
+ }
+#else
setup->quantizedGainOff =
-(MIN(115, setup->total_bits / (10 * (decoder->fs_idx + 1))) + 105 + 5 * (decoder->fs_idx + 1));
+#endif
if (decoder->hrmode && decoder->fs_idx == 5)
{
@@ -461,22 +548,28 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes)
}
totalBits = setup->total_bits;
-
- if (decoder->frame_ms == 2.5) {
+
+#ifdef CR9_C_ADD_1p25MS
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ setup->enable_lpc_weighting = setup->total_bits < 60;
+ totalBits = setup->total_bits * 8.0 * 0.42;
+ }
+#endif
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS) {
setup->enable_lpc_weighting = setup->total_bits < 120;
totalBits = setup->total_bits * 4.0 * (1.0 - 0.4);
}
- if (decoder->frame_ms == 5) {
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS) {
setup->enable_lpc_weighting = (setup->total_bits < 240);
totalBits = setup->total_bits * 2 - 160;
}
- if (decoder->frame_ms == 7.5) {
+ if (decoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS) {
setup->enable_lpc_weighting = (setup->total_bits < 360);
totalBits = round(setup->total_bits * 10 / 7.5);
}
-
- if (decoder->frame_length > 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0)) {
- setup->N_red_tns = 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0);
+
+ if (decoder->frame_length > 40 * ((LC3_FLOAT) (decoder->frame_dms * 1.25 * 10) / 10.0)) {
+ setup->N_red_tns = 40 * ((LC3_FLOAT) (decoder->frame_dms * 1.25 * 10) / 10.0);
setup->fs_red_tns = 40000;
} else {
setup->N_red_tns = decoder->frame_length;
@@ -484,29 +577,48 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes)
}
bitsTmp = totalBits;
-
+
if (bitsTmp < 400 + (decoder->fs_idx - 1) * 80) {
setup->ltpf_conf_beta = 0.4;
setup->ltpf_conf_beta_idx = 0;
+#ifdef CR9_C_ADD_1p25MS
+ setup->ltpf_conf_beta_max = 0.6;
+#endif
} else if (bitsTmp < 480 + (decoder->fs_idx - 1) * 80) {
setup->ltpf_conf_beta = 0.35;
setup->ltpf_conf_beta_idx = 1;
+#ifdef CR9_C_ADD_1p25MS
+ setup->ltpf_conf_beta_max = 0.55;
+#endif
} else if (bitsTmp < 560 + (decoder->fs_idx - 1) * 80) {
setup->ltpf_conf_beta = 0.3;
setup->ltpf_conf_beta_idx = 2;
+#ifdef CR9_C_ADD_1p25MS
+ setup->ltpf_conf_beta_max = 0.5;
+#endif
} else if (bitsTmp < 640 + (decoder->fs_idx - 1) * 80) {
setup->ltpf_conf_beta = 0.25;
setup->ltpf_conf_beta_idx = 3;
+#ifdef CR9_C_ADD_1p25MS
+ setup->ltpf_conf_beta_max = 0.45;
+#endif
} else {
setup->ltpf_conf_beta = 0;
setup->ltpf_conf_beta_idx = -1;
+#ifdef CR9_C_ADD_1p25MS
+ setup->ltpf_conf_beta_max = 0;
+#endif
}
+#ifdef CR9_C_ADD_1p25MS
+ setup->ltpf_gain_step = ( setup->ltpf_conf_beta_max - setup->ltpf_conf_beta ) / LTPF_ADAPTIVE_GAIN_RATE;
+#endif
+
/* No LTPF in hrmode */
if (decoder->hrmode == 1) {
setup->ltpf_conf_beta = 0;
setup->ltpf_conf_beta_idx = -1;
}
-
+
return LC3PLUS_OK;
}
diff --git a/lib_lc3plus/setup_dec_lc3.h b/lib_lc3plus/setup_dec_lc3plus.h
similarity index 77%
rename from lib_lc3plus/setup_dec_lc3.h
rename to lib_lc3plus/setup_dec_lc3plus.h
index c3d26ee8ebe8f0b9ab46380ed6d620d7577ee9d3..5dd3e676136aa9b5e94bb12725306aec94f3382c 100644
--- a/lib_lc3plus/setup_dec_lc3.h
+++ b/lib_lc3plus/setup_dec_lc3plus.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -13,6 +13,7 @@
#include "options.h"
#include "wmc_auto.h"
#include "constants.h"
+#include "lc3plus.h"
/* Channel state and bitrate-derived values go in this struct */
typedef struct {
@@ -38,6 +39,24 @@ typedef struct {
LC3_INT scf_idx[SCF_MAX_PARAM];
uint8_t resBits[MAX_RESBITS_LEN];
LC3_INT tns_idx[TNS_NUMFILTERS_MAX * MAXLAG];
+#ifdef CR9_C_ADD_1p25MS
+ /* 1.25 continuation */
+ LC3_INT16 ltpf_mem_continuation;
+ LC3_INT32 ltpf_param_mem_prev[3];
+ LC3_INT16 ltpf_mem_pitch_prev;
+ LC3_INT16 ltpf_mem_pitch_fr_prev;
+ LC3_INT32 ltpf_mem_beta_idx_prev;
+ LC3_FLOAT ltpf_conf_beta_max;
+ LC3_INT16 ltpf_pitch_stability_counter;
+ LC3_FLOAT ltpf_gain_step;
+ LC3_FLOAT ltpf_mem_gain_prev;
+#ifdef FIX_TX_RX_STRUCT_STEREO
+ LC3_INT32 ltpf_rx_status[2];
+#endif
+#ifdef NEW_SIGNALLING_SCHEME_1p25
+ LC3_INT32 ltpfinfo_frame_cntr; /* individual cntr for each channel */
+#endif
+#endif
LC3_FLOAT prev_fac_ns;
LC3_FLOAT ltpf_mem_x[3 * MAX_LEN];
@@ -62,7 +81,7 @@ typedef struct {
/* Constants and sampling rate derived values go in this struct */
struct LC3PLUS_Dec {
- LC3_FLOAT alpha_type_2_table[PLC_FADEOUT_TYPE_1_IN_MS*10/25]; /* [80] */
+ LC3_FLOAT alpha_type_2_table[PLC_FADEOUT_TYPE_1_IN_MS*100/125]; /* [160] */
DecSetup* channel_setup[MAX_CHANNELS];
const LC3_INT* W_fx;
const LC3_INT* bands_offset;
@@ -73,8 +92,8 @@ struct LC3PLUS_Dec {
LC3_INT fs_idx; /* sampling rate index */
LC3_INT frame_length; /* sampling rate index */
LC3_INT channels; /* number of channels */
- LC3_FLOAT frame_ms; /* frame length in ms (wrong for 44.1) */
- LC3_INT frame_dms; /* frame length in ms * 10 (wrong for 44.1) */
+ LC3PLUS_FrameDuration frame_ms; /* frame length in ms (wrong for 44.1) */
+ LC3PLUS_FrameDuration frame_dms; /* frame length in ms * 10 (wrong for 44.1) */
LC3_INT last_size; /* size of last frame, without error protection */
LC3_INT ep_enabled; /* error protection enabled */
LC3_INT error_report; /* corrected errors in last frame or -1 on error */
@@ -109,6 +128,9 @@ struct LC3PLUS_Dec {
int epmr;
LC3_INT16 combined_channel_coding;
int last_error;
+#ifndef FIX_TX_RX_STRUCT_STEREO
+ LC3_INT ltpf_rx_status[2];
+#endif
};
#endif
diff --git a/lib_lc3plus/setup_enc_lc3.c b/lib_lc3plus/setup_enc_lc3plus.c
similarity index 68%
rename from lib_lc3plus/setup_enc_lc3.c
rename to lib_lc3plus/setup_enc_lc3plus.c
index 750a97bb043fb78f7c3f3f0f6149c470dd8e233d..438a721d061ee358695a07e550a8a641e15f535b 100644
--- a/lib_lc3plus/setup_enc_lc3.c
+++ b/lib_lc3plus/setup_enc_lc3plus.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -9,7 +9,7 @@
#include "options.h"
#include "wmc_auto.h"
-#include "setup_enc_lc3.h"
+#include "setup_enc_lc3plus.h"
#include "functions.h"
#include
@@ -41,7 +41,7 @@ LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels
encoder->fs = CODEC_FS(samplerate);
encoder->fs_in = samplerate;
encoder->fs_idx = FS2FS_IDX(encoder->fs);
- encoder->frame_dms = 100;
+ encoder->frame_dms = LC3PLUS_FRAME_DURATION_10MS;
if (encoder->fs_idx > 4) {
encoder->fs_idx = 5;
@@ -50,7 +50,7 @@ LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels
encoder->hrmode = hrmode != 0;
encoder->channels = channels;
- encoder->frame_ms = 10;
+ encoder->frame_ms = LC3PLUS_FRAME_DURATION_10MS;
encoder->envelope_bits = 38;
encoder->global_gain_bits = 8;
encoder->noise_fac_bits = 3;
@@ -97,6 +97,15 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder)
int ch = 0;
EncSetup* setup;
+#ifdef CR9_C_ADD_1p25MS
+#ifndef FIX_TX_RX_STRUCT_STEREO
+ encoder->Tx_ltpf = 0;
+#endif
+#endif
+#ifdef FIX_FLOAT_LT_NORMCORR_INIT
+ encoder->long_term_norm_corr= (0xFFFF >> 2)/32768.0;
+#endif
+
encoder->frame_length = ceil(encoder->fs * 10 / 1000); /* fs * 0.01*2^6 */
if (encoder->hrmode == 1)
{
@@ -129,7 +138,7 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder)
encoder->BW_cutoff_bits = BW_cutoff_bits_all[encoder->fs_idx];
}
- if (encoder->frame_ms == 10) {
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_10MS) {
encoder->la_zeroes = MDCT_la_zeroes[encoder->fs_idx];
if (encoder->hrmode)
{
@@ -145,7 +154,7 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder)
encoder->attdec_damping = 0.5;
encoder->attdec_hangover_thresh = 2;
}
- else if (encoder->frame_ms == 7.5) {
+ else if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS) {
if (encoder->hrmode)
{
encoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms_HR[encoder->fs_idx];
@@ -176,7 +185,7 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder)
encoder->near_nyquist_index = encoder->bands_number - 4;
encoder->r12k8_mem_out_len = ceil(2.0 * ((LC3_FLOAT) encoder->frame_length / 2.0 - (LC3_FLOAT) encoder->la_zeroes) * 12800.0 / (LC3_FLOAT) encoder->fs - 8.0);
}
- else if (encoder->frame_ms == 5) {
+ else if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS) {
encoder->frame_length = encoder->frame_length >> 1;
encoder->yLen /= 2;
encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes;
@@ -193,8 +202,11 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder)
encoder->bands_offset = ACC_COEFF_PER_BAND_5ms[encoder->fs_idx];
}
encoder->cutoffBins = BW_cutoff_bin_all_5ms;
+#ifdef FIX_LTPF_PITCH_MEM_LEN
+ encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + LEN_12K8 / 2;
+#endif
}
- else if (encoder->frame_ms == 2.5) {
+ else if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS) {
encoder->la_zeroes = MDCT_la_zeroes_2_5ms[encoder->fs_idx];
if (encoder->hrmode)
{
@@ -219,12 +231,53 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder)
encoder->nSubdivisions = 2;
encoder->near_nyquist_index = encoder->bands_number - 2;
+#ifdef FIX_LTPF_PITCH_MEM_LEN
+ encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (3 * (LEN_12K8 / 4));
+#else
encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 2);
+#endif
+ }
+#ifdef CR9_C_ADD_1p25MS
+ else if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ encoder->la_zeroes = MDCT_la_zeroes_1_25ms[encoder->fs_idx];
+ if (encoder->hrmode)
+ {
+ assert(0);
+ }
+ else
+ {
+ encoder->bands_offset = ACC_COEFF_PER_BAND_1_25ms[encoder->fs_idx];
+ }
+ encoder->cutoffBins = BW_cutoff_bin_all_1_25ms;
+ encoder->frame_length = encoder->frame_length >> 3;
+ encoder->yLen /= 8;
+ encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes;
+ if (encoder->hrmode)
+ {
+ assert(0);
+ }
+ else
+ {
+ encoder->bands_number = bands_number_1_25ms[encoder->fs_idx];
+ encoder->BW_cutoff_bits = 0; /* transmit no bw bits */
+ encoder->bw_ctrl_active = 1;
+ }
+
+ encoder->nSubdivisions = 2;
+ encoder->near_nyquist_index = encoder->bands_number - 2;
+#ifdef FIX_LTPF_PITCH_MEM_LEN
+ encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (7 * (LEN_12K8 / 8));
+#else
+ encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 1) + 16;
+#endif
+ encoder->r12k8_mem_out_len = 8;
+
+ encoder->attdec_damping = 32767.0/32768.0;
}
+#endif
for (ch = 0; ch < encoder->channels; ch++) {
setup = encoder->channel_setup[ch];
-
setup->olpa_mem_pitch = 17;
setup->pitch_flag = 0;
if (setup->mdctStruct.mem != NULL) {
@@ -246,32 +299,46 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder)
LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
{
int ch = 0, bitsTmp = 0, minBR = 0, maxBR = 0, totalBytes = 0;
- LC3_INT channel_bytes = 0, max_bytes = 0;
-
+ LC3_INT channel_bytes = 0;
+
#ifdef ENABLE_HR_MODE_FL
+#ifdef CR12_D_FIX_BITRATE_LIMITS
+ LC3_INT fec_slot_bytes_min = 0, check_bytes = 0;
+#else
+ LC3_INT max_bytes = 0;
+#endif
if (encoder->hrmode)
{
switch (encoder->frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ assert(0);
maxBR = 672000;
if (encoder->fs == 48000) {minBR = MIN_BR_25MS_48KHZ_HR;}
else if (encoder->fs == 96000) {minBR = MIN_BR_25MS_96KHZ_HR;}
else { return LC3PLUS_HRMODE_ERROR;}
break;
- case 50:
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
+ maxBR = 672000;
+ if (encoder->fs == 48000) {minBR = MIN_BR_25MS_48KHZ_HR;}
+ else if (encoder->fs == 96000) {minBR = MIN_BR_25MS_96KHZ_HR;}
+ else { return LC3PLUS_HRMODE_ERROR;}
+ break;
+ case LC3PLUS_FRAME_DURATION_5MS:
maxBR = 600000;
if (encoder->fs == 48000) {minBR = MIN_BR_50MS_48KHZ_HR;}
else if (encoder->fs == 96000) {minBR = MIN_BR_50MS_96KHZ_HR;}
else { return LC3PLUS_HRMODE_ERROR;}
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
maxBR = 500000;
if (encoder->fs == 48000) {minBR = MIN_BR_075DMS_48KHZ_HR;}
else if (encoder->fs == 96000) {minBR = MIN_BR_075DMS_96KHZ_HR;}
else {return LC3PLUS_HRMODE_ERROR;}
break;
- case 100:
+ case LC3PLUS_FRAME_DURATION_10MS:
maxBR = 500000;
if (encoder->fs == 48000) {minBR = MIN_BR_100MS_48KHZ_HR;}
else if (encoder->fs == 96000) {minBR = MIN_BR_100MS_96KHZ_HR;}
@@ -289,11 +356,17 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
switch (encoder->frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ minBR = MIN_BR_0125DMS;
+ maxBR = MAX_BR_0125DMS;
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
minBR = MIN_BR_025DMS;
maxBR = MAX_BR;
break;
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
minBR = MIN_BR_050DMS;
maxBR = MAX_BR;
/* have additional limitations for 5.0ms */
@@ -303,7 +376,7 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
default: break;
}
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
minBR = MIN_BR_075DMS;
maxBR = MAX_BR_075DMS;
/* have additional limitations for 7.5ms */
@@ -315,7 +388,7 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
default: break;
}
break;
- case 100:
+ case LC3PLUS_FRAME_DURATION_10MS:
/* have additional limitations for 10ms */
minBR = MIN_BR_100DMS;
maxBR = MAX_BR;
@@ -327,7 +400,8 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
default: maxBR = MAX_BR; break;
}
break;
- default: return LC3PLUS_FRAMEMS_ERROR;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ return LC3PLUS_FRAMEMS_ERROR;
}
maxBR *= (encoder->fs_in == 44100 ? 441. / 480 : 1);
}
@@ -346,8 +420,57 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
if (encoder->epmode > 0)
{
+#ifdef CR12_D_FIX_BITRATE_LIMITS
+#ifdef ENABLE_HR_MODE_FL
+ if (encoder->hrmode){
+ switch( encoder->frame_dms )
+ {
+ case LC3PLUS_FRAME_DURATION_2p5MS:
+ if( encoder->fs_in == 48000){
+ fec_slot_bytes_min = FEC_SLOT_BYTES_MIN_025DMS_48KHZ_HR;
+ } else {
+ fec_slot_bytes_min = FEC_SLOT_BYTES_MIN_025DMS_96KHZ_HR;
+ }
+ break;
+ case LC3PLUS_FRAME_DURATION_5MS:
+ if( encoder->fs_in == 48000){
+ fec_slot_bytes_min = FEC_SLOT_BYTES_MIN_050DMS_48KHZ_HR;
+ } else {
+ fec_slot_bytes_min = FEC_SLOT_BYTES_MIN_050DMS_96KHZ_HR;
+ }
+ break;
+ case LC3PLUS_FRAME_DURATION_7p5MS:
+ if( encoder->fs_in == 48000){
+ fec_slot_bytes_min = FEC_SLOT_BYTES_MIN_075DMS_48KHZ_HR;
+ } else {
+ fec_slot_bytes_min = FEC_SLOT_BYTES_MIN_075DMS_96KHZ_HR;
+ }
+ break;
+ case LC3PLUS_FRAME_DURATION_10MS:
+ if( encoder->fs_in == 48000){
+ fec_slot_bytes_min = FEC_SLOT_BYTES_MIN_100DMS_48KHZ_HR;
+ } else {
+ fec_slot_bytes_min = FEC_SLOT_BYTES_MIN_100DMS_96KHZ_HR;
+ }
+ break;
+ default:
+ return LC3PLUS_FRAMEMS_ERROR;
+ }
+ }
+ else
+#endif
+ {
+ fec_slot_bytes_min = FEC_SLOT_BYTES_MIN;
+ }
+
+
+ check_bytes = bitrate * encoder->frame_length / ( 8 * encoder->fs_in * encoder->channels );
+ maxBR = FEC_SLOT_BYTES_MAX * ( 8 * encoder->fs_in * encoder->channels ) / encoder->frame_length;
+ if ( check_bytes < fec_slot_bytes_min || bitrate > maxBR )
+#else
max_bytes = bitrate * encoder->frame_length / (8 * encoder->fs_in * encoder->channels);
if (max_bytes < FEC_SLOT_BYTES_MIN || max_bytes > FEC_SLOT_BYTES_MAX)
+#endif /* CR12_D_FIX_BITRATE_LIMITS */
{
encoder->lc3_br_set = 0;
return LC3PLUS_BITRATE_ERROR;
@@ -371,7 +494,7 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
totalBytes = bitrate * encoder->frame_length / (8 * encoder->fs_in);
}
- if (encoder->frame_dms <= 50)
+ if (encoder->frame_dms <= LC3PLUS_FRAME_DURATION_5MS)
{
encoder->tnsMaxOrder = 4;
} else {
@@ -400,8 +523,8 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
setup->n_pccw = fec_get_n_pccw(channel_bytes, encoder->epmode, encoder->combined_channel_coding);
setup->n_pc = fec_get_n_pc(encoder->epmode, setup->n_pccw, channel_bytes);
}
- // reduce bandwith to 12kHz if bitrate is low
- if (encoder->frame_dms == 100 &&
+ /* reduce bandwith to 12kHz if bitrate is low */
+ if (encoder->frame_dms == LC3PLUS_FRAME_DURATION_10MS &&
((setup->targetBytes < 40 && encoder->fs == 48000) ||
(setup->targetBytes < 36 && encoder->fs == 32000)))
{
@@ -413,12 +536,12 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
For a second channel with lower targetBytes, bandwidth is overwritten */
encoder->bandwidth = encoder->bandwidth_preset;
}
- encoder->bw_ctrl_cutoff_bin = encoder->bandwidth * encoder->frame_dms / 5000;
+ encoder->bw_ctrl_cutoff_bin = encoder->bandwidth * (encoder->frame_dms * 1.25 * 10) / 5000;
encoder->bw_index = (encoder->bandwidth / 4000) - 1;
setup->total_bits = setup->targetBytes << 3;
setup->targetBitsInit = setup->total_bits - encoder->envelope_bits - encoder->global_gain_bits -
encoder->noise_fac_bits - encoder->BW_cutoff_bits -
- ceil(LC3_LOGTWO(encoder->frame_length / 2)) - 2 - 1;
+ getLastNzBits (encoder->frame_length) - 2 - 1;
if (setup->total_bits > 1280) {
setup->targetBitsInit = setup->targetBitsInit - 1;
@@ -435,30 +558,45 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
setup->targetBitsAri = setup->total_bits;
setup->enable_lpc_weighting = setup->total_bits < 480;
- if (encoder->frame_ms == 7.5) {
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS) {
setup->enable_lpc_weighting = setup->total_bits < 360;
}
- if (encoder->frame_ms == 5) {
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS) {
setup->enable_lpc_weighting = setup->total_bits < 240;
}
- if (encoder->frame_ms == 2.5) {
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS) {
setup->enable_lpc_weighting = setup->total_bits < 120;
}
-
+#ifdef CR9_C_ADD_1p25MS
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ setup->enable_lpc_weighting = setup->total_bits < 60;
+ }
+#endif
+#ifdef FIX_BOTH_1p25_WB_GLOBGAINOFFSET_NONBE
+ if (encoder->frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ setup->quantizedGainOff = calc_GGainOffset_1p25(setup->total_bits, encoder->fs_idx); /* enc/dec common function */
+ }
+ else
+ {
+ setup->quantizedGainOff =
+ -(MIN(115, setup->total_bits / (10 * (encoder->fs_idx + 1))) + 105 + 5 * (encoder->fs_idx + 1));
+ }
+#else
setup->quantizedGainOff =
-(MIN(115, setup->total_bits / (10 * (encoder->fs_idx + 1))) + 105 + 5 * (encoder->fs_idx + 1));
-
+#endif
if (encoder->hrmode && encoder->fs_idx == 5)
{
setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181);
}
- if (encoder->frame_ms == 10 && ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) ||
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_10MS && ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) ||
(encoder->fs_in == 32000 && setup->targetBytes >= 81)) && setup->targetBytes < 340 && encoder->hrmode == 0) {
setup->attack_handling = 1;
}
- else if (encoder->frame_dms == 75 && ((encoder->fs_in >= 44100 && setup->targetBytes >= 75) ||
+ else if (encoder->frame_dms == LC3PLUS_FRAME_DURATION_7p5MS && ((encoder->fs_in >= 44100 && setup->targetBytes >= 75) ||
(encoder->fs_in == 32000 && setup->targetBytes >= 61)) && setup->targetBytes < 150 && encoder->hrmode == 0)
{
setup->attack_handling = 1;
@@ -477,13 +615,18 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
}
bitsTmp = setup->total_bits;
- if (encoder->frame_ms == 2.5) {
+#ifdef CR9_C_ADD_1p25MS
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ bitsTmp = bitsTmp * 8.0 * 0.42;
+ }
+#endif
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS) {
bitsTmp = bitsTmp * 4.0 * (1.0 - 0.4);
}
- if (encoder->frame_ms == 5) {
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS) {
bitsTmp = bitsTmp * 2 - 160;
}
- if (encoder->frame_ms == 7.5) {
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS) {
bitsTmp = round(bitsTmp * 10 / 7.5);
}
@@ -508,68 +651,89 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate)
} else {
encoder->sns_damping = 0.6;
if (encoder->fs_idx >= 4) {
- if (encoder->frame_ms == 10)
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_10MS)
{
if (setup->total_bits > 4400) {
encoder->sns_damping = 6881.0/32768.0;
}
}
- if (encoder->frame_ms == 7.5)
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS)
{
if (setup->total_bits > 3*4400/4) {
encoder->sns_damping = 5898.0/32768.0;
}
}
- if (encoder->frame_ms == 5)
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS)
{
if (setup->total_bits > 4600/2) {
encoder->sns_damping = 4915.0/32768.0;
}
}
- if (encoder->frame_ms == 2.5)
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS)
{
if (setup->total_bits > 4600/4) {
encoder->sns_damping = 4915.0/32768.0;
}
}
+#ifdef CR9_C_ADD_1p25MS
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ assert(0);
+ if (setup->total_bits > 4600/4) {
+ encoder->sns_damping = 4915.0/32768.0;
+ }
+ }
+#endif
}
}
if (encoder->hrmode && encoder->fs_idx >= 4)
{
- int real_rate = setup->targetBytes * 8000 / encoder->frame_ms;
+ int real_rate = setup->targetBytes * 8000 / (encoder->frame_ms * 1.25);
setup->regBits = real_rate / 12500;
if (encoder->fs_idx == 5)
{
- if (encoder->frame_ms == 10)
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_10MS)
{
setup->regBits +=2;
}
- if (encoder->frame_ms == 7.5)
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS)
{
setup->regBits +=1;
}
- if (encoder->frame_ms == 2.5)
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS)
{
setup->regBits -= 6;
}
+#ifdef CR9_C_ADD_1p25MS
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ assert(0);
+ }
+#endif
}
else
{
- if (encoder->frame_ms == 2.5)
+#ifdef CR9_C_ADD_1p25MS
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ assert(0);
+ }
+#endif
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_2p5MS)
{
setup->regBits -= 6;
}
- else if (encoder->frame_ms == 5)
+ else if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_5MS)
{
setup->regBits += 0;
}
- if (encoder->frame_ms == 7.5)
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_7p5MS)
{
setup->regBits +=2;
}
- if (encoder->frame_ms == 10)
+ if (encoder->frame_ms == LC3PLUS_FRAME_DURATION_10MS)
{
setup->regBits += 5;
}
diff --git a/lib_lc3plus/setup_enc_lc3.h b/lib_lc3plus/setup_enc_lc3plus.h
similarity index 87%
rename from lib_lc3plus/setup_enc_lc3.h
rename to lib_lc3plus/setup_enc_lc3plus.h
index 7947a0e649dc352909a54ff500c9165082f02763..1f1656f36510afc6ff44c0300c20e49981543fcb 100644
--- a/lib_lc3plus/setup_enc_lc3.h
+++ b/lib_lc3plus/setup_enc_lc3plus.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -13,11 +13,19 @@
#include "options.h"
#include "wmc_auto.h"
#include "constants.h"
+#include "lc3plus.h"
/* Channel state and bitrate-derived values go in this struct */
typedef struct {
LC3_FLOAT targetBitsOff;
+#ifdef CR9_C_ADD_1p25MS
+ LC3_FLOAT ltpf_mem_normcorr[LEN_MEM_NORMCORR];
+#else
LC3_FLOAT ltpf_mem_normcorr;
+#endif
+#ifdef FIX_TX_RX_STRUCT_STEREO
+ LC3_INT16 Tx_ltpf;
+#endif
LC3_FLOAT ltpf_mem_mem_normcorr;
LC3_FLOAT attdec_filter_mem[2];
LC3_FLOAT attdec_acc_energy;
@@ -83,8 +91,8 @@ struct LC3PLUS_Enc {
LC3_INT frame_length; /* audio samples / frame */
LC3_INT channels; /* number of channels */
LC3_INT epmode; /* error protection mode */
- LC3_FLOAT frame_ms; /* frame length in ms (wrong for 44.1) */
- LC3_INT frame_dms; /* frame length in ms * 10 (wrong for 44.1) */
+ LC3PLUS_FrameDuration frame_ms; /* enum for frame length in ms (wrong for 44.1) */
+ LC3PLUS_FrameDuration frame_dms; /* enum for frame length in ms * 10 (wrong for 44.1) */
LC3_INT tilt;
LC3_INT lc3_br_set;
LC3_INT yLen;
@@ -109,10 +117,14 @@ struct LC3PLUS_Enc {
LC3_INT bw_ctrl_active;
LC3_INT bw_ctrl_cutoff_bin;
LC3_INT bw_index;
- LC3_FLOAT sns_damping;
LC3_INT attdec_nblocks;
- LC3_FLOAT attdec_damping;
LC3_INT attdec_hangover_thresh;
+#ifndef FIX_TX_RX_STRUCT_STEREO
+ LC3_INT16 Tx_ltpf;
+#endif
+ LC3_FLOAT long_term_norm_corr;
+ LC3_FLOAT attdec_damping;
+ LC3_FLOAT sns_damping;
LC3_INT16 combined_channel_coding;
LC3_INT16 epmr;
diff --git a/lib_lc3plus/sns_compute_scf.c b/lib_lc3plus/sns_compute_scf.c
index d81c61c42acaf4e68a585cac3776f8284cb21980..6358985e8bbf5273178a6c42b78b32063c6618f9 100644
--- a/lib_lc3plus/sns_compute_scf.c
+++ b/lib_lc3plus/sns_compute_scf.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,18 +11,53 @@
#include "wmc_auto.h"
#include "functions.h"
-void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx)
+#ifdef CR9_C_ADD_1p25MS
+static float limitShaping (LC3_FLOAT* xl4 ) {
+ LC3_FLOAT fac;
+ LC3_FLOAT score;
+ LC3_FLOAT min_fac;
+ LC3_FLOAT max_fac;
+ LC3_FLOAT start;
+ LC3_FLOAT stop;
+
+ min_fac = 1.f;
+ max_fac = 0.3f;
+ start = 5.f;
+ stop = 8.f;
+
+ score = ((2.f*(xl4[0]-xl4[1])) + (xl4[0]-xl4[2])) / 2.f;
+ score = fmin(fmax(score, start), stop);
+
+ fac = (stop-score)/(stop-start);
+ return ((min_fac - max_fac) * fac + max_fac);
+}
+#endif
+
+void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx
+#ifdef CR9_C_ADD_1p25MS
+ , LC3PLUS_FrameDuration frame_dms, LC3_FLOAT *LT_normcorr, LC3_FLOAT normcorr
+#endif
+ )
{
LC3_INT bands_number, d, i, j, n, n2, n4, mapping[64];
- LC3_FLOAT x_tmp1[MAX_LEN], sum, mean, nf, gains_smooth[M], ratio;
- LC3_FLOAT sum_gains_smooth;
- const LC3_FLOAT* sns_preemph;
+ LC3_FLOAT x_tmp1[MAX_LEN], sum = 0, mean, nf, gains_smooth[M], ratio;
+ LC3_FLOAT sum_gains_smooth = 0;
+#ifdef CR9_C_ADD_1p25MS
+ LC3_FLOAT fac;
+ LC3_FLOAT start;
+ LC3_FLOAT limiterGain;
+#endif
+ const LC3_FLOAT *sns_preemph_adapt, *sns_preemph;
+ bands_number = xLen;
- sum_gains_smooth = 0; sum = 0;
sns_preemph = sns_preemph_all[fs_idx];
- bands_number = xLen;
- assert(bands_number <= 64);
+#ifdef CR9_C_ADD_1p25MS
+ limiterGain = 1.f;
+ sns_preemph_adapt = sns_preemph_adaptMaxTilt_all[fs_idx];
+#else
+ (void) sns_preemph_adapt;
+#endif
/* 5 ms */
if (bands_number < 64) {
@@ -90,9 +125,29 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_I
x[63] = 0.5 * x[63] + 0.25 * (x_tmp1[63] + x[63]);
/* Pre-emphasis */
+#ifdef CR9_C_ADD_1p25MS
+ if (sns_preemph_adapt != NULL && frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ {
+ *LT_normcorr = normcorr * 0.125f + *LT_normcorr * 0.875f;
+
+ start = 0.8f; /* adaptive preemphasis active from start to 1.0 */
+ fac = (fmax(*LT_normcorr - start, 0) * (1. / (1.-start)));
+
+ for (i = 0; i < 64; i++) {
+ x[i] = x[i] * (sns_preemph[i] + fac*sns_preemph_adapt[i]);
+ }
+ }
+ else
+ {
+ for (i = 0; i < 64; i++) {
+ x[i] = x[i] * sns_preemph[i];
+ }
+ }
+#else
for (i = 0; i < 64; i++) {
x[i] = x[i] * sns_preemph[i];
}
+#endif
/* Noise floor at -40dB */
for (i = 0; i < 64; i++) {
@@ -139,17 +194,57 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_I
gains_smooth[n] = sum;
sum_gains_smooth += sum;
}
-
-
+#ifdef CR9_C_ADD_1p25MS
+ /* limit shaping */
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) {
+ limiterGain *= limitShaping(gains_smooth);
+ }
+#endif
/* Remove mean and scaling */
mean = sum_gains_smooth / 16.0;
for (i = 0; i < 16; i++) {
+#ifdef CR9_C_ADD_1p25MS
+ gains[i] = limiterGain * sns_damping * (gains_smooth[i] - mean);
+#else
gains[i] = sns_damping * (gains_smooth[i] - mean);
+#endif
}
/* Smoothing */
- if (smooth) {
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+ if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
+ { /* smoothing loop for 1.25 ms */
+
+ const LC3_FLOAT A0 = 3.0 / 16.0; /* 2/16= 0.125, 3/16 = 0.1875 */
+ const LC3_FLOAT A1 = (1.0 - 2 * A0);
+ const LC3_FLOAT A2 = A0;
+
+ gains_smooth[0] = A0 * (gains[0] + gains[1]) * 0.5 + A1 * gains[0] + A2 * gains[1];
+ /* BASOP-loop:: preload gains[-1] with 0.5*(gains[0]+gains[1]) */
+ for (i = 1; i < (M - 1); i++)
+ {
+ gains_smooth[i] = A0 * gains[i - 1] + A1 * gains[i] + A2 * gains[i + 1];
+ }
+ gains_smooth[M - 1] = A0 * gains[M - 2] + A1 * gains[M - 1] + A2 * 0.5 * (gains[M - 2] + gains[M - 1]);
+ /* BASOP-loop :: preload gains[M] with 0.5*(gains[M-2]+gains[M-1]) */
+ sum = 0;
+ for (i = 0; i < M; i++)
+ {
+ sum += gains_smooth[i];
+ }
+
+ mean = sum / (LC3_FLOAT)M;
+ for (i = 0; i < M; i++)
+ {
+ gains[i] = attdec_damping_factor * (gains_smooth[i] - mean);
+ }
+ }
+ else if (smooth == 1) /* original attack smoothing */
+#else
+ if (smooth)
+#endif
+ {
gains_smooth[0] = (gains[0] + gains[1] + gains[2]) / 3.0;
gains_smooth[1] = (gains[0] + gains[1] + gains[2] + gains[3]) / 4.0;
diff --git a/lib_lc3plus/sns_interpolate_scf.c b/lib_lc3plus/sns_interpolate_scf.c
index 15ae55c12a8598bba030bcdae43da4fc53315144..d421154f5354c3c28118d6da679073ba7a00137d 100644
--- a/lib_lc3plus/sns_interpolate_scf.c
+++ b/lib_lc3plus/sns_interpolate_scf.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -70,7 +70,8 @@ void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT
}
move_float(gains_int, tmp, bands_number);
- } else {
+ }
+ else {
assert(0 && "Unsupported number of bands!");
}
}
diff --git a/lib_lc3plus/sns_quantize_scf.c b/lib_lc3plus/sns_quantize_scf.c
index 96d8cdb4b604b43fb319e52a4f012a184b8989a4..9079217128488b8964e5849fe08213c7b3504059 100644
--- a/lib_lc3plus/sns_quantize_scf.c
+++ b/lib_lc3plus/sns_quantize_scf.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -11,8 +11,158 @@
#include "wmc_auto.h"
#include "functions.h"
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+
+static LC3_INT16 get_lead_sign( LC3_UINT32* ind_in );
+static void mind2vec_one( LC3_UINT8 k_val_in, LC3_INT16 leading_sign, LC3_INT32* vec_out );
+
+LC3_INT16 get_lead_sign( LC3_UINT32* ind_in )
+{
+ LC3_INT16 leading_sign;
+ leading_sign = +1;
+ if ( ( ( *ind_in ) & 0x1 ) != 0 )
+ {
+ leading_sign = -1;
+ }
+ ( *ind_in ) = ( *ind_in >> 1 );
+
+ return leading_sign;
+}
+
+void mind2vec_one( LC3_UINT8 k_val_in, /* i: nb unit pulses */
+ LC3_INT16 leading_sign, /* i: leading sign -1, 1 */
+ LC3_INT32* vec_out /* o: updated pulse train */ )
+{
+ LC3_INT32 amp;
+ amp = k_val_in;
+ if ( leading_sign < 0 )
+ {
+ amp = -k_val_in;
+ }
+ *vec_out = amp;
+}
+
+static LC3_UINT8 setval_update_sign( LC3_INT16 k_delta, LC3_UINT8 k_max_local_in, LC3_INT16* leading_sign, LC3_UINT32* ind_in, LC3_INT32* vec_out );
+
+static void mind2vec_tab( LC3_UINT8 dim_in, LC3_UINT8 k_max_local, LC3_INT16 leading_sign, LC3_UINT32 ind, LC3_INT32* vec_out );
+
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+static void MPVQdeenum( LC3_UINT8 dim_in, LC3_UINT8 k_val_in, LC3_INT32 LS_ind, LC3_INT32 MPVQ_ind, LC3_INT32* vec_out );
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+
+LC3_UINT8 setval_update_sign( LC3_INT16 k_delta, /* i */
+ LC3_UINT8 k_max_local_in, /* i */
+ LC3_INT16* leading_sign, /* i/o */
+ LC3_UINT32* ind_in, /* i/o */
+ LC3_INT32* vec_out /* i/o */ )
+{
+ LC3_UINT8 k_max_local_out;
+ k_max_local_out = k_max_local_in;
+ if ( k_delta != 0 )
+ {
+ mind2vec_one( k_delta, *leading_sign, vec_out );
+ *leading_sign = get_lead_sign( ind_in );
+ k_max_local_out -= k_delta;
+ }
+
+ return k_max_local_out;
+}
+
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+
+void mind2vec_tab( LC3_UINT8 dim_in, /* i: dimension */
+ LC3_UINT8 k_max_local, /* i: nb unit pulses */
+ LC3_INT16 leading_sign, /* i: leading sign */
+ LC3_UINT32 ind, /* i: MPVQ-index */
+ LC3_INT32* vec_out /* o: pulse train */ )
+{
+ /* pvq_enc_A = MPVQ_offsets */
+ LC3_UINT8 pos, k_acc;
+ LC3_UINT32 UL_tmp_offset;
+ LC3_INT32 UL_diff;
+ LC3_INT16 wrap_flag, k_delta;
+ const LC3_UINT32* h_row_ptr;
+ /* init */
+ h_row_ptr = &( pvq_enc_A[( dim_in - 1 )][0] );
+ k_acc = k_max_local;
+
+ /* loop over positions */
+ for ( pos = 0; pos < dim_in; pos++ )
+ {
+ if ( ind != 0 )
+ {
+ k_acc = k_max_local;
+ UL_tmp_offset = h_row_ptr[k_acc];
+
+ wrap_flag = ( ind < UL_tmp_offset );
+ UL_diff = (LC3_INT32) ( (LC3_INT32) ind - (LC3_INT32) UL_tmp_offset );
+
+ while ( wrap_flag != 0 )
+ {
+ k_acc--;
+ wrap_flag = ( ind < h_row_ptr[k_acc] );
+ UL_diff = (LC3_INT32) ( (LC3_INT32) ind - (LC3_INT32) h_row_ptr[k_acc] );
+ }
+ ind = UL_diff;
+ k_delta = k_max_local - k_acc;
+ }
+ else
+ {
+ mind2vec_one( k_max_local, leading_sign, &vec_out[pos] );
+ break;
+ }
+ k_max_local = setval_update_sign( k_delta, k_max_local, &leading_sign, &ind, &vec_out[pos] );
+ h_row_ptr -= 11; /* reduce dimension in MPVQ_offsets table */
+ }
+}
+
+#endif
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+
+void MPVQdeenum( LC3_UINT8 dim_in, /* i : dimension of vec_out */
+ LC3_UINT8 k_val_in, /* i : number of unit pulses */
+ LC3_INT32 LS_ind, /* i : leading sign index */
+ LC3_INT32 MPVQ_ind, /* i : MPVQ shape index */
+ LC3_INT32* vec_out /* o : PVQ integer pulse train */ )
+{
+ LC3_INT32 leading_sign;
+
+
+ leading_sign = 1;
+ if ( LS_ind != 0 )
+ {
+ leading_sign = -1;
+ }
+
+ mind2vec_tab( dim_in, k_val_in, leading_sign, MPVQ_ind, vec_out );
+}
+
+/* local funcs*/
+
+static void FESSdeenum(LC3_UINT8 dim_in, /* i : dimension of vec_out */
+ LC3_UINT8 n_env, /* i : number envelopes */
+ LC3_UINT8 n_shift, /* i : number shifts */
+ LC3_UINT8 n_signs, /* i : number signs */
+ LC3_INT32 env_ind, /* i:indx */
+ LC3_INT32 shift_ind, /* i:indx */
+ LC3_INT32 sign_ind, /* i:indx */
+ LC3_INT32* vec_out /* o : FESS integer pulse train */);
+
+LC3_INT32 snsQuantScfEncLRSt1ABC(LC3_FLOAT* env, LC3_INT32* L_index, LC3_FLOAT *min_mse_saveBCA_ptr,
+ LC3_INT32* ind_saveB_ptr, LC3_FLOAT* st1_vectors,
+ LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx);
+
+#endif /* CR9_C_ADD_1p25MS_LRSNS*/
+
static void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses);
-static LC3_INT find_last_indice_le(LC3_INT compare, const LC3_INT* array, LC3_INT len);
+static LC3_INT find_last_indice_le(LC3_INT compare, const LC3_UINT32* array, LC3_INT len);
static void idct_II(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT len);
void idct_II(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT len)
@@ -28,6 +178,87 @@ void idct_II(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT len)
}
}
+#ifdef FIX_FLOAT_ENC_PVQ_PULSE_LOOP
+static LC3_INT32 pvq_pulse_search_lc(LC3_FLOAT* xabs, LC3_FLOAT* ener, LC3_FLOAT* corr, LC3_INT32* y, LC3_INT32 start, LC3_INT32 end)
+{
+ Dyn_Mem_Deluxe_In(
+ LC3_INT32 i;
+ LC3_INT32 nBest;
+ LC3_FLOAT max_norm_ratio, cand_norm_ratio;
+ LC3_FLOAT currCorr;
+ LC3_INT32 currEnInt;
+ const LC3_FLOAT* isqrt_QxTab;
+ );
+
+ const LC3_INT16 isqrt_Q16tab[1 + 64] = { /* table generated using ISqrt16 function + shift to Q16 */
+ 32767, 32767, 32767, 32767, 32766, 29308, 26754, 24770, 23169, 21844,
+ 20723, 19759, 18918, 18176, 17515, 16921, 16383, 15894, 15446, 15034,
+ 14654, 14300, 13972, 13665, 13377, 13107, 12852, 12612, 12385, 12169,
+ 11965, 11770, 11584, 11407, 11238, 11077, 10922, 10773, 10631, 10493,
+ 10361, 10234, 10112, 9993, 9879, 9769, 9662, 9559, 9459, 9362,
+ 9268, 9176, 9088, 9001, 8918, 8836, 8757, 8680, 8605, 8532,
+ 8460, 8390, 8323, 8256, 8191
+ };
+ LC3_FLOAT isqrt_Q16tabFlt[1 + 64];
+
+ const LC3_INT16 isqrt_Q15tab[1 + 6] = {
+ /* onepulse_search_tab based search , Q15 table generated using isqrt_Q16tab table for idx=[8(4*2),16(4*4), 20(4*5),24(4*6) ] */
+ /* this slighly suboptimal inv_sqrt(x) table is used to enable optional exact use of the ROM saving BASOP ISqrt16() function */
+
+ 32767/*0*/, 32766/*1*/, 23169 /*2*/, 18918 /*3*/ , 16384/*4*/ , 14654 /*5*/, 13377/*6*/
+ /* i.e. value in isqrt_Q15tab[n=0..6] == isqrt_Q16tab[4*n] */
+ };
+ LC3_FLOAT isqrt_Q15tabFlt[1 + 6];
+
+ for ( i = 0; i <= 64; i++ )
+ {
+ isqrt_Q16tabFlt[i] = isqrt_Q16tab[i] / 65536.0;
+ }
+ for (i = 0; i <= 6; i++)
+ {
+ isqrt_Q15tabFlt[i] = isqrt_Q15tab[i] / 32768.0;
+ }
+
+
+ isqrt_QxTab = isqrt_Q16tabFlt; /* Q16 table valid for energies 4...64 */
+
+ assert( *ener >= 0.0 );
+ *ener += 1.0; /* Added once for the entire loop */
+ if (*ener <= 3.0 ) /* +1 for the inloop value of *ener was preadded before */
+ {
+ isqrt_QxTab = isqrt_Q15tabFlt; /* energies: 1...6 */
+ }
+
+ nBest = -1;
+ max_norm_ratio = -1.0;
+ /* Iterative max search using tabulated inv sqrt */
+ for ( i = start; i < end; i++)
+ {
+ currCorr = *corr + xabs[i];
+ currEnInt = ((LC3_INT32) *ener) + (2 * y[i]);
+
+ cand_norm_ratio = currCorr * isqrt_QxTab[currEnInt];
+
+ if ( cand_norm_ratio >= max_norm_ratio )
+ {
+ nBest = i;
+ }
+ max_norm_ratio = LC3_FMAX(max_norm_ratio, cand_norm_ratio); /* always update */
+ }
+
+ *corr += xabs[nBest];
+ *ener += (2 * y[nBest]);
+
+ assert(nBest >= 0);
+ assert(nBest <=M);
+ assert(*ener <= 64.0);
+ y[nBest] += 1; /* Add the selected unit pulse */
+
+ Dyn_Mem_Deluxe_Out();
+ return nBest;
+}
+#endif
+
static LC3_INT pvq_pulse_search(LC3_FLOAT *xabs, LC3_FLOAT *ener, LC3_FLOAT *corr, LC3_INT *y, LC3_INT start, LC3_INT end)
{
LC3_INT i;
@@ -39,7 +270,7 @@ static LC3_INT pvq_pulse_search(LC3_FLOAT *xabs, LC3_FLOAT *ener, LC3_FLOAT *cor
bestCorrSq = 0.0;
bestEn = 0.0;
- *ener += 1; // Added once for the entire loop
+ *ener += 1; /* Added once for the entire loop */
i = start;
@@ -194,7 +425,7 @@ static void pvq_enc_search(LC3_FLOAT* x_in, LC3_INT y[4][M])
return;
}
-static inline LC3_FLOAT calc_mse(LC3_FLOAT *t2rot, LC3_FLOAT *y, LC3_FLOAT gain, LC3_INT N)
+static LC3_FLOAT calc_mse(LC3_FLOAT *t2rot, LC3_FLOAT *y, LC3_FLOAT gain, LC3_INT N)
{
LC3_FLOAT mse;
LC3_INT i;
@@ -402,12 +633,12 @@ void process_snsQuantizesScf_Enc(LC3_FLOAT* env, LC3_INT* index, LC3_FLOAT* envq
}
}
-LC3_INT find_last_indice_le(LC3_INT compare, const LC3_INT* array, LC3_INT len)
+LC3_INT find_last_indice_le(LC3_INT compare, const LC3_UINT32* array, LC3_INT len)
{
LC3_INT idx = 0, i = 0;
for (i = 0; i < len; i++) {
- if (compare >= array[i]) {
+ if ((LC3_UINT32)compare >= array[i]) {
idx++;
}
}
@@ -510,3 +741,1345 @@ void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q)
scf_q[i] += st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]];
}
}
+
+#ifdef CR9_C_ADD_1p25MS_LRSNS
+
+/* 29/30 bits optimized search functions for PVQ and FESS */
+/* stage 2 submode shape 0: "splitLF" (N=5,K=6)(N=8,K=2) or (N=5,K=8)(N=8,K=0) , 4 gains */
+/* stage 2 submode shape 1: "full" FB (N=15,K=5), 4xfixed , 8 gains */
+/* stage 2 submode shape 2-5: "fixed env " (N=13-15,K=10-12), 4xfixed , 8 gains */
+
+static void pvq_fess_enc_search(LC3_FLOAT* x_in /* i: 0...M-1 */
+ , LC3_INT32 y[SNSLR_MAX_PVQ_SEARCH_CAND][M], /* o: [3]*[0...M-1] */
+ LC3_INT32 *fixShapeNb /* o: [-1, 0...3] */
+)
+{
+ LC3_INT32 i, j, curr_cand;
+ LC3_INT32 NcandLF, Ngrp, Kgrp, Ktop_LF, Ntop_LF;
+ LC3_INT32 NcandFB, Kfull;
+ LC3_INT32 NcandFix, Kfix, Nsigns_fix;
+
+ LC3_INT32 N, K, pulse_total, top_pulses;
+ LC3_FLOAT abs_sum, projfac;
+ LC3_FLOAT yy, xy; /* in-loop energy and corr */
+
+ LC3_FLOAT yy_n5k8, xy_n5k8;
+ LC3_FLOAT xabs[M];
+ LC3_INT32 y_tmp_n5k8[M];
+ LC3_INT32 y_tmp[M];
+ LC3_INT16 n, fix_ind, shift_ind;
+ LC3_INT16 best_env_ind;
+ LC3_INT16 best_shift_ind;
+ LC3_INT16 best_ind;
+ LC3_INT16 pulse_total_n5k8;
+ LC3_FLOAT f_normcorr_fixenv[SNSLR_N_FIXENV][SNSLR_N_FIXENV_SHIFTS];
+ LC3_FLOAT *p;
+ const LC3_INT32* env_ptr;
+
+#define SC 1 /*Starting coeff position of PVQ target , (we have no DC) */
+ {
+ /* no DC coeff , only coeff 1..15 is quantized in the range 0..15 */
+ NcandLF = 1;
+
+ Ngrp = 5; /* PVQ(5, 6) = 10.94b , + P(8,2)=7b + P(2,0)=0b */
+ Kgrp = 6;
+ Ntop_LF = 8; /* allow to encode less than M-sc -Ngrp */
+ Ktop_LF = 2; /* fill a few unit pulses in the HF region */
+ /* P(5,8)+P(10,0) will also fit in 13 bits */
+ /* Fullband safety net */
+ NcandFB = 1;
+ Kfull = 5; ; /* PVQ(15,5)= 16.65 bits , */
+
+ /*fixed env */
+ NcandFix = 4; /* 4th only has 10 signs */
+ Kfix = 12; /* number of signs */
+ Nsigns_fix = 12; /* area to cover and number of signs */
+ }
+
+ for (i = SC; i < (M); i++)
+ {
+ xabs[i] = LC3_FABS(x_in[i]);
+ }
+ xabs[0] = 0;
+
+ /* splitLF LFfocus subshape idx 0 */
+ if (Kgrp > 0 && NcandLF > 0)
+ {
+ curr_cand = 0;
+ /* Projection to LF pyramid N=Ngrp, K=Kgrp */
+ abs_sum = 0.0;
+ N = Ngrp;
+ K = Kgrp;
+ pulse_total = 0;
+
+ for (i = SC; i < (SC + N); i++)
+ {
+ abs_sum += xabs[i];
+ }
+ projfac = (K - 1) / abs_sum;
+
+ if (abs_sum == 0.0)
+ {
+ projfac = 0.0;
+ }
+
+ yy = xy = 0.0f;
+ for (i = SC; i < (SC + N); i++)
+ {
+ y_tmp[i] = LC3_FLOOR(xabs[i] * projfac); /* local projection within group over N coeffs used here */
+
+ pulse_total += y_tmp[i];
+
+ yy += (y_tmp[i] * y_tmp[i]);
+ xy += (xabs[i] * y_tmp[i]);
+ }
+
+ /* LF Adding unit pulses up to K in LF */
+ for (; pulse_total < K; pulse_total++)
+ {
+ pvq_pulse_search(xabs, &yy, &xy, y_tmp, SC, SC + N);
+ }
+
+ {
+ /* allow (N=5,K=(6+2)=8) in low band only, higher part is then zeroed */
+ /* can be multiplexed put in 13 bits */
+ yy_n5k8 = yy;
+ xy_n5k8 = xy;
+ pulse_total_n5k8 = pulse_total;
+
+ memset(y_tmp_n5k8, 0, sizeof(*y_tmp_n5k8)*M);
+ memcpy(y_tmp_n5k8, y_tmp, sizeof(*y_tmp)*(SC + N)); /* cpy LF initial search result for n5k6 to n5k8 output */
+
+ for (; pulse_total_n5k8 < (K + 2); pulse_total_n5k8++)
+ {
+ pvq_pulse_search(xabs, &yy_n5k8, &xy_n5k8, y_tmp_n5k8, SC, SC + N);
+ }
+ }
+
+
+ /* split HF : longer M vector */
+ memset(y[curr_cand], 0, sizeof(*y_tmp)*M); /*zero full candidate vector */
+ memcpy(&(y[curr_cand]), y_tmp, sizeof(*y_tmp)*(SC + N)); /* cpy LF-part to output */
+
+
+ if (Ktop_LF && (M - Ngrp - SC >= Ntop_LF))
+ {
+
+ /* xy = 0.0; yy = 0.0; */
+ memset(&(y_tmp[Ngrp]), 0, (M - SC - Ngrp) * sizeof(*y_tmp));
+ top_pulses = 0;
+
+ for (; top_pulses < Ktop_LF; top_pulses++)
+ {
+ pvq_pulse_search(xabs, &yy, &xy, y_tmp, SC + N, SC + N + Ntop_LF);
+ }
+
+ for (j = SC + N; j < (SC + N + Ntop_LF); j++)
+ {
+ y[curr_cand][j] = y_tmp[j];
+ }
+ }
+
+ {
+ /* shape 0 : decide on best split alternative "0a" n5k6 + n8k2 + n2k0 or "0b" n5k8 + n10k0,
+ shape only assessed , i.e. assume same gain quantizer */
+ if ((xy_n5k8*xy_n5k8)*yy > (xy*xy)*yy_n5k8)
+ {
+ /* use n5k8, with zeroed high band */
+ /* i.e. better to put two additional pulses in the n5 low band than in the higher band */
+ memcpy(&(y[curr_cand]), y_tmp_n5k8, sizeof(*y_tmp_n5k8)*(M)); /* cpy LFonly to output */
+ }
+ }
+
+ /* assign signs to the cand vector from x_in */
+ for (i = SC; i < (M); i++)
+ {
+ if (x_in[i] < 0)
+ {
+ y[curr_cand][i] *= -1;
+ }
+ }
+ y[curr_cand][0] = 0; /* DC */
+
+ }
+
+ /* shape 1 : Full band shape analysis */
+ if (Kfull > 0 && NcandFB > 0)
+ {
+ curr_cand = 1;
+ N = M - SC;
+ K = Kfull;
+
+ /* project */
+ pulse_total = 0;
+ yy = xy = 0.0f;
+ abs_sum = 0.0;
+ for (i = SC; i < SC + N; i++)
+ {
+ abs_sum += xabs[i];/* over N */
+ }
+
+ projfac = (K - 1) / abs_sum;
+ if (abs_sum == 0.0)
+ {
+ projfac = 0.0;
+ }
+
+
+ memset(y_tmp, 0, sizeof(*y_tmp)*M);
+ for (i = SC; i < SC + N; i++)
+ {
+ y_tmp[i] = LC3_FLOOR(xabs[i] * projfac); /* projection over N coeffs */
+ pulse_total += y_tmp[i];
+ yy += (y_tmp[i] * y_tmp[i]);
+ xy += (xabs[i] * y_tmp[i]);
+ }
+
+ for (; pulse_total < K; pulse_total++)
+ {
+ pvq_pulse_search(xabs, &yy, &xy, y_tmp, SC, SC + N);
+ }
+ memcpy(&(y[curr_cand]), y_tmp, sizeof(*y_tmp)*M); /* cpy to output */
+
+ /* Step: Add signs to each of the full vector from input */
+ for (i = SC; i < M; i++)
+ {
+ if (x_in[i] < 0)
+ {
+ y[curr_cand][i] *= -1; ;
+ }
+ }
+ y[curr_cand][0] = 0;
+ } /* Fullband */
+
+
+ { /* fixed envelopes shifted signs shapes 2 ... 5 */
+ best_env_ind = -1;
+ best_shift_ind = -1;
+
+ /* search fixed env shapes first */
+ /* search shape of all fixed flat-ish envelopes using an optimal nb_env*nbshifts shape analysis */
+ if (Kfix > 0 && NcandFix > 0)
+ {
+ curr_cand = 2;
+ N = Nsigns_fix;
+ K = Kfix;
+
+ /* find the minimum shape error across all possible 4 fixed envelopes and all 4 shifts */
+ /* maximise normalized cross correlation target*y *(1/sqrt(y^2)) to minimize shape error */
+
+ for (fix_ind = 0; fix_ind < SNSLR_N_FIXENV; fix_ind++)
+ {
+ for (shift_ind = 0; shift_ind < SNSLR_N_FIXENV_SHIFTS; shift_ind++)
+ {
+ f_normcorr_fixenv[fix_ind][shift_ind] = 0.0;
+ for (n = 0; n < signs_fix[fix_ind]; n++)
+ {
+ f_normcorr_fixenv[fix_ind][shift_ind] += (xabs[SC + n + shift_ind] * env_ptrs[fix_ind][n + shift_ind]);
+ }
+ /* energy normalize, for the specific shift and env,
+ otherwise it is not possible to compare among the shifted envelopes properly */
+
+ f_normcorr_fixenv[fix_ind][shift_ind] *= shift_en_norm_factors[fix_ind][shift_ind];
+ }
+ }
+
+ /* now actually pick the env[0,1,2,3] and env shift[0,1,2,3] option which maximizes the normcorr
+ (minimizes shape mse as all fixed envelopes have the same gain quantizer) */
+ p = &(f_normcorr_fixenv[0][0]);
+ best_ind = 0;
+ for (n = 1; n < (SNSLR_N_FIXENV * SNSLR_N_FIXENV_SHIFTS); n++)
+ {
+ if (p[n] > p[best_ind])
+ {
+ best_ind = n;
+ }
+ }
+ best_env_ind = best_ind / SNSLR_N_FIXENV_SHIFTS;
+ best_shift_ind = best_ind - best_env_ind * SNSLR_N_FIXENV;
+ assert(best_env_ind >= 0 && best_env_ind < SNSLR_N_FIXENV);
+ assert(best_shift_ind >= 0 && best_shift_ind < SNSLR_N_FIXENV_SHIFTS);
+ }
+ /* o: best_shift_ind; o: best_env_ind */
+
+ *fixShapeNb = best_env_ind; /* best normalized correlation out of the 4x4 = 16 envelope options */
+ /*best shift ind, later re-established/found via output vector y[2] */
+
+ /* Fixed envelope "flat-ish" signband coding , including sign coding of shifted block */
+ /* submode idx 2,3,4 , "1"/env 1(s0)+ 2(shift)+ 11bits(s1..s11) + always a 3 bits gain */
+ /* submode idx 5 , "1"/env 1(s0)+ 2(shift)+ 9bits(s1..s9) + always a 3 bits gain */
+ /*
+ 2, init_bell_12signs , [ 8,8,8, 7,7 ... ]
+ 3, decaying envelope 12 signs, [ 12,12,11,11, ... ]
+ 4, start_bell_12signs ,[ 7,7,8,8,8, 7,... ]
+ 5, early_bell_10signs,[ 6,6, 7,7,8,8,8,7,... ]
+ */
+
+ {
+ /* construct the selected fix shape with its corresponding shift */
+ memset(y[curr_cand], 0, sizeof(LC3_INT32)*M); /* zero output */
+ env_ptr = env_ptrs[best_env_ind];
+
+ Nsigns_fix = signs_fix[best_env_ind];
+
+ /* now assign unit amplitude and signs to each of the fixed env vector from x_in in the band */
+ for (i = best_shift_ind; i < (Nsigns_fix + best_shift_ind); i++)
+ {
+ y[curr_cand][SC + i] = env_ptr[i];
+ }
+ for (i = (SC + best_shift_ind); i < (SC + Nsigns_fix + best_shift_ind); i++)
+ {
+ if (x_in[i] < 0)
+ {
+ y[curr_cand][i] *= -1;
+ }
+ }
+ y[curr_cand][0] = 0;
+ }
+ }
+
+ return;
+}
+
+static void lrsns_quant_shape_gain(
+ LC3_FLOAT* t2rot, LC3_INT32 y[SNSLR_MAX_PVQ_SEARCH_CAND][M],
+ LC3_INT32* gain_idx, LC3_INT32 *shape_idx, LC3_FLOAT* y_norm, LC3_FLOAT* scq_gain, LC3_INT32 n_cand )
+{
+ LC3_INT32 gidx, sidx;
+ LC3_FLOAT min_mse, mse;
+
+ LC3_INT32 i;
+ LC3_INT16 start_shape;
+ LC3_INT16 end_shape;
+ LC3_INT32 gain_levels[SNSLR_MAX_PVQ_SEARCH_CAND];
+ LC3_FLOAT yCur[SNSLR_MAX_PVQ_SEARCH_CAND][M];
+ const LC3_FLOAT *lrsns_vq_gains[SNSLR_MAX_PVQ_SEARCH_CAND];
+
+ gain_levels[0] = 4; /* splitLF */
+ gain_levels[1] = 8; /* full */
+ gain_levels[2] = 8; /* Fix-env{ 0,1,2,3,4} */
+
+ lrsns_vq_gains[0] = &(lrsns_gains_Q11[0][0]);
+ lrsns_vq_gains[1] = &(lrsns_gains_Q11[1][0]);
+ lrsns_vq_gains[2] = &(lrsns_gains_Q11[2][0]);
+
+ min_mse = LC3_CONST_FLOATMAX;
+
+
+ *gain_idx = 0;
+ *shape_idx = 0;
+ start_shape = 0;
+ end_shape = n_cand;
+
+ for (sidx = start_shape; sidx < end_shape; sidx++)
+ {
+ /* Normalize the vectors */
+ for (i = 0; i < M; i++)
+ {
+ yCur[sidx][i] = (LC3_FLOAT)y[sidx][i];
+ }
+ pvq_enc_vec_normalize(yCur[sidx], M);
+
+ for (gidx = 0; gidx < gain_levels[sidx]; gidx++)
+ {
+ mse = calc_mse(t2rot, yCur[sidx], lrsns_vq_gains[sidx][gidx], M);
+
+ if (mse < min_mse)
+ {
+ *gain_idx = gidx;
+ *shape_idx = sidx;
+ min_mse = mse;
+ }
+ }
+
+ }
+
+ for (i = 0; i < M; i++)
+ {
+ y_norm[i] = yCur[*shape_idx][i];
+ }
+
+ *scq_gain = lrsns_vq_gains[*shape_idx][*gain_idx];
+
+ return;
+}
+
+LC3_INT32 MSEsearchGeneric(LC3_FLOAT *scf, const LC3_FLOAT *sns_CB, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT* min_mse)
+{
+
+ LC3_FLOAT f_tmp, mse;
+ LC3_INT32 i, n, ind;
+
+ ind = -1;
+
+ *min_mse = (LC3_FLOAT)LC3_CONST_POW_2_100;
+ for (i = 0; i < cb_len; i++)
+ {
+ mse = 0;
+ for (n = 0; n < v_len; n++)
+ {
+ f_tmp = (scf[n] - sns_CB[i * v_len + n]);
+ mse += (f_tmp * f_tmp);
+ }
+
+ if (mse < *min_mse)
+ {
+ *min_mse = mse;
+ ind = i;
+ }
+ }
+ assert(ind >= 0 && ind < cb_len);
+
+ return ind;
+}
+
+void snslr_st1B_vector_dec(LC3_INT16 idx, const LC3_INT16* LFCB, const LC3_INT16 *HFCB, const LC3_INT16* seg_cnt_cum, const LC3_INT16* idx12b_cb, LC3_FLOAT *st1B_vector)
+{
+ /* decompose the received 0 ... 169 index , into the correct intger and float st1B vector */
+ LC3_INT32 i, seg; /*counters*/
+ const LC3_INT16 *lf_cb, *hf_cb;
+ LC3_INT16 idx_12b, lf_sign, hf_sign;
+ LC3_INT16 idx_LF, idx_HF;
+ LC3_INT16 buf[M];
+ LC3_INT16 st1B_W16Q11[M];
+ LC3_FLOAT f_Q11_scale = (1.0 / 2048.0);
+
+ assert(idx >= 0 && idx < 170);
+ seg = 0;
+ while (seg_cnt_cum[seg + 1] <= idx) {
+ seg++;
+ }
+ assert(seg >= 0 && seg < 4);
+
+ idx_12b = idx12b_cb[idx]; /* from sequential value to a coded 12b index*/
+
+ lf_sign = 1; /* assume a 0 bit -> "+" */
+ if ((0x0800 & idx_12b) != 0) {
+ lf_sign = -1; /* assume a 1 bit -> " -" */
+ }
+
+ hf_sign = 1; /* assume a 0 bit -> "+" */
+ if ((0x0400 & idx_12b) != 0) {
+ hf_sign = -1; /* assume a 1 bit -> "-" */
+ }
+ idx_LF = (0x03e0 & idx_12b) >> 5;
+ idx_HF = (0x001f & idx_12b);
+
+ /* extseg0 f,f */
+ lf_cb = &(LFCB[idx_LF*(M / 2)]);
+ hf_cb = &(HFCB[idx_HF*(M / 2)]);
+ for (i = 0; i < (M / 2); i++)
+ {
+ st1B_W16Q11[i] = lf_sign * lf_cb[i]; /* imult() or negate */
+ st1B_W16Q11[M / 2 + i] = hf_sign * hf_cb[i];
+ }
+ memcpy(buf, st1B_W16Q11, sizeof(*buf)*M); /* buffer cpy needed for reversal sections */
+
+ if ((seg & 0x0002) != 0)
+ { /* r,* */ /* flip LF */
+ for (i = 0; i < (M / 2); i++)
+ {
+ st1B_W16Q11[i] = buf[(M / 2 - 1) - i];
+ }
+ }
+
+ if ((seg & 0x0001) != 0)
+ { /* *,r */ /* flip HF */
+ for (i = 0; i < (M / 2); i++)
+ {
+ st1B_W16Q11[(M / 2) + i] = buf[(M - 1) - i];
+ }
+ }
+
+ /* Cfloat: convert the 16bit integer Q11 values from LFCB, and HFCB into floats */
+ for (i = 0; i < M; i++)
+ {
+ st1B_vector[i] = ((LC3_FLOAT)st1B_W16Q11[i]) * f_Q11_scale;
+ }
+}
+
+LC3_INT32 MSEsearchCbBIdxMap(const LC3_FLOAT *scf, const LC3_INT16 *LFCB, const LC3_INT16 *HFCB, const LC3_INT16 *seg_cnt_cum, const LC3_INT16* idx12b_cb, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT* min_mse)
+{
+ LC3_INT32 seg, i, j; /*counters */
+ LC3_INT32 L_mse;
+ LC3_INT16 scfLF_Q11[M], tmp_buf[M];
+ LC3_INT16* scfHF_Q11;
+ const LC3_INT16 *lf_cb, *hf_cb;
+ LC3_INT16 err, best_ind, idx_12b, signbitLF, signbitHF, idx_LF, idx_HF;
+ LC3_INT32 L_mse_best = INT_MAX; /*a huge positive number */
+
+ UNUSED(cb_len); /*cb_len only used for assert/verification */
+
+ assert(v_len == M);
+
+ scfHF_Q11 = (&scfLF_Q11[v_len / 2]); /* ptr init */
+
+ /*set up fwd,fwd search */
+ for (i = 0; i < M; i++)
+ {
+ tmp_buf[i] = (LC3_INT16)LC3_ROUND(scf[i] * 2048.0); /* scf target moved to BASOP signed Word16Q11 integer domain */
+ }
+
+ best_ind = -1; /*for debug*/
+ for (seg = 0; seg < 4; seg++)
+ {
+ memcpy(scfLF_Q11, tmp_buf, M * sizeof(*scfLF_Q11)); /* M * move16() */
+ /*seg==0: fwd, fwd */
+ /*seg==1: fwd, rev */
+ /*seg==2: fwd, fwd */
+ /*seg==3: rev, rev */
+
+ if ((seg & 0x0002) != 0)
+ { /* {r,*} */ /* flip LF */
+ for (i = 0; i < (M / 2); i++)
+ {
+ scfLF_Q11[i] = tmp_buf[(M / 2 - 1) - i];
+ }
+ }
+ if ((seg & 0x0001) != 0)
+ { /* {*,r} */ /* flip HF */
+ for (i = 0; i < (M / 2); i++)
+ {
+ scfLF_Q11[M / 2 + i] = tmp_buf[(M - 1) - i];
+ }
+ }
+
+ for (i = seg_cnt_cum[seg]; i < seg_cnt_cum[seg + 1]; i++)
+ {
+ idx_12b = idx12b_cb[i]; /* indirect adressing lookup of 12b index pointing to LF and HF + individual sign swaps */
+ signbitLF = (0x0800 & idx_12b); /* b11 logical */
+ signbitHF = (0x0400 & idx_12b); /* b10 logical */
+ idx_LF = (0x03e0 & idx_12b) >> 5; /* b9...b5 */
+ idx_HF = (0x001f & idx_12b); /* b4..b0 lowest 5 bits */
+
+ lf_cb = &(LFCB[idx_LF * M / 2]); /* ptr init */
+ hf_cb = &(HFCB[idx_HF * M / 2]); /* ptr init */
+
+ L_mse = 0; /* move32() */ /* we accumulate energies on the positive side */
+ for (j = 0; j < (M / 2); j++)
+ {
+ err = (scfLF_Q11[j] - lf_cb[j]); /* a "+"sign, LF err in Q11 */
+ if (signbitLF != 0)
+ { /* negate LF*/
+ err = (scfLF_Q11[j] + lf_cb[j]); /* "-""-" --> "+" LF err in Q11 ,single BASOP */
+ }
+ L_mse += (err * err); /* simulate L_mac0 , accumulate towards max positive side */
+
+ err = (scfHF_Q11[j] - hf_cb[j]); /* a "+"sign, HF err in Q11 */
+ if (signbitHF != 0)
+ { /* negate HF */
+ err = (scfHF_Q11[j] + hf_cb[j]); /* -- --> "+", LF err in Q11 ,single BASOP */
+ }
+ L_mse += (err * err); /*simulate L_mac0 */ /* now total error */
+ }
+
+ L_mse_best = MIN(L_mse, L_mse_best); /* 1 cycle BASOP preupdate best */
+ if ((L_mse - L_mse_best) == 0)
+ {
+ best_ind = i; /* update winner, single BASOP */
+ }
+ }
+ }/* segment seg */
+
+ *min_mse = (LC3_FLOAT)((double)L_mse_best) / (2048.0*2048.0); /* Word32 mse -> Cfloat output calculation */
+
+ assert(best_ind >= 0 && best_ind < cb_len);
+
+ return (LC3_INT32)best_ind;
+}
+
+void snslr_st1C_vector_dec(LC3_INT16 idx, const LC3_INT8* CBW8, LC3_INT16 scaleQ4, LC3_INT16 inv_scaleQ15, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT *st1C_vector)
+{
+ /* decompose the received 0... 169 index , into the correct (integer and) float st1C vector */
+ /* even in C-float the st1C coeffs are put into a S16Q11 final integers domain */
+ /* Enables BE compatibility between {BASOP, float, double} arithmetic implmentations */
+
+
+ LC3_INT32 i; /*counter*/
+ const LC3_INT8 *cb;
+ LC3_INT32 L_tmp;
+ LC3_INT16 s_tmp, st1C_Q11[M];
+
+ UNUSED(v_len);
+ UNUSED(cb_len);
+ UNUSED(inv_scaleQ15); /* req for debugging only */
+ assert(idx >= 0 && idx < cb_len);
+ assert(v_len == M);
+
+ cb = &(CBW8[idx*M]); /* pointer init */
+ for (i = 0; i < (M); i++)
+ {
+ /* BASOP: L_tmp = L_mult0((int16_t)cb[i], scaleQ4 ); */ /*S8Q7 * S15Q4 */ /*sign+7bit, sign+4 bits --> sign+11bit .lt sign+23 bits*/
+ L_tmp = ((int16_t)cb[i] /*S8Q7*/ * scaleQ4 /* S16Q4 */); /* S32Q11 */
+
+ /* Cfloat: convert to Word16 Q11 integer as Word16 Q11 SNS domain bits, and then into floats */
+ assert(L_tmp >= -32768L && L_tmp <= 32767L); /* INT16 domain check*/
+ s_tmp = (int16_t)(L_tmp);
+ st1C_Q11[i] = s_tmp;
+ }
+
+ /* Cfloat: convert the Word16 Q11 SNS domain bits, and then into floats */
+ for (i = 0; i < M; i++)
+ {
+ st1C_vector[i] = ((LC3_FLOAT)st1C_Q11[i])*(1.0 / 2048.0);
+ }
+}
+
+LC3_INT32 MSEsearchGenericScaledW8(LC3_FLOAT *scf, const LC3_INT8 *sns_CBW8, LC3_INT16 scaleQ4, LC3_INT16 inv_scaleQ15, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT* min_mse)
+{
+ /* scf float input values are typically in the range +12.0 to -12.0.
+ ROM table stored in WORD8 [+127,-128], format corresponding to ]+1.0 .. -1.0 ]
+ inv_scaleQ15, [downscaling value in Q15] applied before search
+ scaleQ12 upscaling value quantized in Q12, used in the mse calulation and in the common float and BASOP synthesis routines
+
+ L_mse evaluated here in a positive integer Word32 domain to match BASOP
+
+ Fuzzing/saturation considerations
+ max M==16 values (4 bits) yields 16*(256*256)=>2^(4+8+8)=2^20 .lt 2^31,
+ IntegerWord32 is a safe search domain
+
+ a WC input analysis would be when half target entries are "-256" and half +255
+
+ */
+ LC3_INT32 i, n, best_ind; /*counters*/
+ LC3_INT32 L_mse, L_mse_best;
+ LC3_INT16 targetW16[M], err;
+ LC3_FLOAT f_tmp, f_scale;
+ const LC3_INT8 * cbW8;
+
+ f_scale = ((LC3_FLOAT)inv_scaleQ15) / 32768.0;
+ for (i = 0; i < v_len; i++) {
+ f_tmp = (scf[i] * f_scale);
+ assert(f_tmp >= -4.0 && f_tmp < 4.0); /* check for about 2 bit integer margin in the target */
+ targetW16[i] = (LC3_INT16)LC3_FLOOR(f_tmp*128.0); /*cast to INT16 W8Q7 */
+ };
+ /* in BASOP 1/32768 and *128 is handled by one single shift) */
+
+ L_mse_best = INT_MAX; /* largest possible positive number in INT32 */
+ best_ind = -1;
+
+ for (i = 0; i < cb_len; i++) {
+ L_mse = (0L); /* move32() */
+ /* we accumulate energies on the positive side Word8 vectors do not have any issue with saturation (16*256*256) ==2^(4+8+8) .lt 2^31 MAX_INT */
+
+ cbW8 = &sns_CBW8[i*v_len]; /*ptr init */
+ for (n = 0; n < v_len; n++)
+ {
+ err = (targetW16[n] - ((LC3_INT16)cbW8[n])); /* cast from Word8 to Word16 is not for free,
+ actual cost in a Word16 architecture is a L_and(x,0x00ffff) or a shr(x,8) */
+
+ L_mse += (err*err); /* L_mse = L_mac0(L_mse, err, err); */
+ }
+
+ if ((L_mse - L_mse_best) <= 0)
+ { /* a value closer to 0 */
+ best_ind = i; /* single BASOP for best idx update */
+ }
+ L_mse_best = MIN(L_mse, L_mse_best); /* always update best MSE using L_min() in the idx loop, reduces WC WMOPS */
+ }
+ assert(best_ind >= 0 && best_ind < cb_len);
+
+
+ *min_mse = (LC3_FLOAT)((double)(L_mse_best)) / (128.0*128.0); /* Word32 L_mse in Q7 -> Cfloat output calculation */
+
+ f_tmp = (((double)scaleQ4) / 16.0);
+ *min_mse *= (f_tmp*f_tmp); /* make gain scaling a part of Word32 L_mse -> Cfloat output calculation */
+
+ return best_ind;
+}
+
+/* LRSNS stage 1 functionality */
+LC3_INT32 snsQuantScfEncLRSt1ABC(LC3_FLOAT* env, LC3_INT32* L_index, LC3_FLOAT *min_mse_saveBCA_ptr,
+ LC3_INT32* ind_saveB_ptr, LC3_FLOAT* st1_vectors, LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx)
+{
+
+ LC3_INT32 i;
+ LC3_FLOAT *st1_vector, *st1_vectorA, *st1_vectorB, *st1_vectorC, target[M];
+ LC3_FLOAT st1_vectorBC[M];
+ LC3_FLOAT min_mse_saveA, min_mse_saveB, min_mse_saveC, min_mse_saveBC;
+ LC3_INT32 ind_saveA, ind_saveC;
+ const LC3_FLOAT *cb;
+ LC3_INT16 stage1_mode; /*0=A, 1=B, 2=C. -1==fail*/
+ LC3_FLOAT min_mse_saveB_fxlike;
+ LC3_INT32 ind_saveB_fxlike = -1;
+ LC3_FLOAT st1_vectorB_idx[M];
+ LC3_FLOAT st1C_lim;
+ LC3_FLOAT f_mse_tmp;
+ LC3_INT32 ind_saveC_ScaledW8 = -1;
+ LC3_FLOAT min_mse_saveC_ScaledW8;
+
+#ifdef LRSNS_CBC_NO_LTPF_DEPENDENCY
+ UNUSED(ltpf_rx);
+#endif
+
+ stage1_mode = -1; /* output mode */
+
+ st1_vectorA = &(st1_vectors[0]);
+ st1_vectorB = &(st1_vectors[1 * M]);
+ st1_vectorC = &(st1_vectors[2 * M]);
+ st1_vector = &(st1_vectors[3 * M]);
+
+ /* snslr stage1 B(170) and C(170), A(2) evaluation */
+ /* b0-b8 b9
+ segm , idx9b , stop bit, comment use
+ -----+--------+---------
+ A | 510,511| n/a, 2 entries, 9 bit total
+ ------+--------+--------
+ ------+--------+--------+-------
+ B | 0--169 | 1 , 170 entries, 10 bit total
+ ------+--------+--------
+ C | 170-339| 1 , 170 entries, 10 bit total
+ ------+--------+--------+------------
+ ------+--------+--------+------------
+ B* | 340-509| 1 --> aux=1, 170, 3b+17b for stage2 'LR_full/LR_fix', 30 bit total
+ ------+--------+--------+-------
+ B* | 0--169 | 0 , --> aux=0, 170, 2b+17b for stage2 'LR_SplitLF' , 29 bit total
+ ------+--------+--------+-------
+ B* | 170-339| 0 , --> aux=1, 170, 2b+17b for stage2 'LR_SplitLF',29 bit total
+ ------+--------+--------+-------
+ B* | 340-509| 0 --> aux=0, 170, 3b+17b for stage2 'LR_full/LR_fix', 30 bit total
+ ------+--------+--------+-------
+ */
+
+ { /* stage 1 section A(2), a very small 2xM entry cb */
+ cb = lrsns_st1A_topTab_1bitNoDC;
+
+ memcpy(target, env, sizeof(LC3_FLOAT)*M);
+
+ ind_saveA = MSEsearchGeneric(target, cb, M, 2, &min_mse_saveA);
+ memcpy(st1_vectorA, &(cb[ind_saveA*M]), sizeof(LC3_FLOAT)*M);
+ }
+
+ min_mse_saveB = LC3_CONST_FLOATMAX; /*safety init*/
+
+ { /* stage1 section B(170) MSE analysis */
+ memcpy(target, env, sizeof(LC3_FLOAT)*M);
+ *ind_saveB_ptr = -1;
+
+ ind_saveB_fxlike = MSEsearchCbBIdxMap(target, st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11,
+ lrsns_st1B_merged170orderSortedSegmCum, lrsns_st1B_merged170orderSort12bitIdx, M, 170, &min_mse_saveB_fxlike); /*st1B LF,HF idx lookup search 170 ,170 Word16s , 0.34kB ROM */
+ snslr_st1B_vector_dec(ind_saveB_fxlike, st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, lrsns_st1B_merged170orderSortedSegmCum, lrsns_st1B_merged170orderSort12bitIdx,
+ st1_vectorB_idx);
+
+ *ind_saveB_ptr = ind_saveB_fxlike;
+ min_mse_saveB = min_mse_saveB_fxlike;
+ memcpy(st1_vectorB, st1_vectorB_idx, sizeof(LC3_FLOAT)*M); /*use low ROM version */
+
+ {
+ /* remove DC that can remain in the LF,HF index stored stage cb B structure */
+ /* a very slight offline decrease in perf 0.001 dB in AvSD when searching with DC above,
+ but it allows much better stage1 ROM-reuse performance
+ */
+ LC3_FLOAT dc = snslr_remove_st1_DC_fQ11(st1_vectorB, M); /* inplace removal of dc in st1_vectorB */
+ LC3_FLOAT f_tmp;
+ assert(min_mse_saveB >= 0.0);
+
+ f_tmp = min_mse_saveB - M * (dc*dc);
+ min_mse_saveB = MAX(f_tmp, 0.0); /* truncation in DC removal can cause negative MSE, limit to 0 */
+ }
+ } /* end of stage 1 section B , search */
+
+
+
+ st1C_lim = 3.97; /* corresponding to an SD limit of = 1.5 */
+ f_mse_tmp = MIN(min_mse_saveA*0.875, min_mse_saveB);
+
+ if (f_mse_tmp < st1C_lim) /* skip C search if SD is already low enough < 1.5dB) to save average WMOPS */
+
+ {
+ min_mse_saveC = 2 * 5.579999923706055; /*disable C selection in consecutive logic */
+ ind_saveC = 0; /* a valid index that will not be used */
+ }
+ else
+ { /* search stage1 C */
+ /* search another set (pitch dependent section C) of 170 mean residual vectors */
+ /* pitch_info rx selects a mean and then employ a trained residual 1x170W8 based harmonic outlier table */
+
+ /* float means are based on Word16 S16Q11 values, so that BASOP and float always may become BE in synthesis*/
+ int16_t CBCmeanp_ind = pitch_rx; /* 0 or 1 */
+
+#ifndef LRSNS_CBC_NO_LTPF_DEPENDENCY
+ if (pitch_rx != 0 && ltpf_rx != 0)
+ {
+ CBCmeanp_ind = CBCmeanp_ind + 1; /*LTPF_rx is also active */
+ }
+#else
+ /* CbC only dependent on LTP transmission on/off */
+#endif
+
+ for (i = 0; i < M; i++)
+ {
+ target[i] = env[i] - lrsns_st1CTrainedMapMeans[CBCmeanp_ind][i];
+ }
+
+ ind_saveC_ScaledW8 = MSEsearchGenericScaledW8(target, lrsns_st1C_Both_Word8,
+ lrsns_st1C_Both_scaleQ4_7p4bits_fx[1], lrsns_st1C_Both_inv_scaleQ15_7p4bits_fx[1],
+ M, 170, &(min_mse_saveC_ScaledW8));
+
+ snslr_st1C_vector_dec(ind_saveC_ScaledW8, lrsns_st1C_Both_Word8, lrsns_st1C_Both_scaleQ4_7p4bits_fx[1], lrsns_st1C_Both_inv_scaleQ15_7p4bits_fx[1],
+ M, 170, st1_vectorC);
+ /* integer based decoder side synthesis of scaled W8 table for best possible interop */
+
+ ind_saveC = ind_saveC_ScaledW8;
+ min_mse_saveC = min_mse_saveC_ScaledW8;
+
+ for (i = 0; i < M; i++) {
+ st1_vectorC[i] += lrsns_st1CTrainedMapMeans[CBCmeanp_ind][i]; /* Q11 means*/
+ }
+ }
+
+ /* BC stage1 comparison */
+ /* initially assume B as stage 1 winner */
+ min_mse_saveBC = min_mse_saveB;
+ L_index[0] = *ind_saveB_ptr; /* 0...169 */
+
+ memcpy(st1_vector, st1_vectorB, sizeof(LC3_FLOAT)*M); /* stage 1 segmentB result without DC copied as base for st2 */
+
+
+ if (min_mse_saveC < min_mse_saveBC)
+ { /* C better than B */
+ min_mse_saveBC = min_mse_saveC;
+ L_index[0] = 170 + ind_saveC; /* [2x 170] (9+1)b [170-339] , ">=170" is a signal to multiplexor */
+ memcpy(st1_vector, st1_vectorC, sizeof(LC3_FLOAT)*M);
+ }
+
+ memcpy(st1_vectorBC, st1_vector, sizeof(LC3_FLOAT)*M);
+ L_index[1] = -10;
+ assert(min_mse_saveBC >= 0.0);
+
+ /* (9(A)<->10(BC) bit weighted comparison */
+ *min_mse_saveBCA_ptr = min_mse_saveBC;
+ if (min_mse_saveA*0.875 < min_mse_saveBC) /* a minor favouring of the 9b vector results sqrt(0.875) => approx 0.6dB level domain */
+ {
+ L_index[0] = 510 + ind_saveA; /* only [510, 511] possible */
+ L_index[1] = -9;
+
+ cb = lrsns_st1A_topTab_1bitNoDC;
+ memcpy(st1_vectorA, &(cb[ind_saveA*M]), sizeof(LC3_FLOAT)*M);
+ memcpy(st1_vector, st1_vectorA, sizeof(LC3_FLOAT)*M);
+
+ *min_mse_saveBCA_ptr = min_mse_saveA * 0.875;;
+ }
+
+ /* index0_saveBCA = index[0];*/ /* 0 ... 511 */
+ /* index1_saveBCA = index[1];*/ /* -9 or -10 */
+
+ stage1_mode = 2; /* C , assumed */
+ if (L_index[0] >= 510)
+ {
+ stage1_mode = 0; /* A */
+ }
+ if (L_index[0] <= 169) {
+ stage1_mode = 1; /* B */
+ }
+
+ return stage1_mode; /* return best stage1 mode */
+}
+
+LC3_INT16 snsQuantScfEncLR(LC3_FLOAT* env, LC3_INT32* L_index, LC3_FLOAT* envq, Dct2 dct2structSNS, LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx)
+{
+ LC3_INT32 i;
+ LC3_FLOAT min_mse_saveBCA;
+ LC3_INT32 ind_saveB;
+ LC3_INT16 st1_mode;
+
+ LC3_FLOAT stage2_en1_norm_sub[M];
+ LC3_FLOAT st1_vectors[(SNSLR_MAX_PVQ_SEARCH_CAND+1)*M], *st1_vectorA, *st1_vectorB, *st1_vectorC, *st1_vector;
+ LC3_FLOAT pvq_target_pre[M];
+ LC3_FLOAT pvq_target[M];
+#ifdef LRSNS_WMC_FIX
+ LC3_INT32 y[SNSLR_MAX_PVQ_SEARCH_CAND][M]; /* o: [3]*[0...M-1] */
+#else
+ LC3_INT32 y_tmp[3*M];
+#endif
+ LC3_FLOAT stage2_en1_norm_pre_sub[M];
+ LC3_FLOAT envq_st1B_st2[M];
+ LC3_FLOAT mse_st1B_st2;
+ LC3_FLOAT mse_st1B_st2_dct_domain;
+ LC3_INT32 gain_idx, shape;
+ LC3_FLOAT scfq_gain;
+ LC3_INT32 fix_shape_idx;
+ LC3_INT16 envelope_bits; /* function output */
+ LC3_INT32 fix_shift_ind, fix_shift_bits, fix_end_sign, LS_tmp_ind;
+ LC3_INT32 shape_local;
+
+ UNUSED(fix_shift_bits); /* used for assert */
+
+#ifndef LRSNS_WMC_FIX
+ LC3_INT32(*y)[M]; /* C-construct to allow matrix adressing into a scratch area */
+#endif
+ envelope_bits = -1; /* output : 9,10, 29/30 */
+ gain_idx = 1; /* stage 2 gain idx range 0 ... 7 , or 0 ... 3 */
+ shape = -1; /* stage 2 shape range 0 ... 5 */
+
+ st1_vectorA = &(st1_vectors[0]);
+ st1_vectorB = &(st1_vectors[1 * M]);
+ st1_vectorC = &(st1_vectors[2 * M]);
+ st1_vector = &(st1_vectors[3 * M]);
+
+
+#ifndef LRSNS_WMC_FIX
+ y = (LC3_INT32(*)[M]) &(y_tmp[0]); /* y is an NxM Matrix Ptr */
+#endif
+ { /* stage1 A,B,C */
+
+ ind_saveB = -1;
+ min_mse_saveBCA = M * 32.0*32.0;
+ st1_mode = snsQuantScfEncLRSt1ABC(
+ env, L_index, &min_mse_saveBCA, &ind_saveB, st1_vectors, pitch_rx, ltpf_rx);
+
+ if (ind_saveB < 0 || ind_saveB > 169)
+ {
+ assert(ind_saveB >= 0 && ind_saveB <= 169); /* idxB always needed in case stage2 is activated */
+ }
+
+ if (st1_mode == 0)
+ {
+ envelope_bits = 9;
+ memcpy(st1_vector, st1_vectorA, sizeof(LC3_FLOAT)*M);
+ assert(L_index[0] >= 510 && L_index[0] <= 511);
+ }
+
+ if (st1_mode == 1)
+ {
+ envelope_bits = 10;
+ memcpy(st1_vector, st1_vectorB, sizeof(LC3_FLOAT)*M);
+ assert(L_index[0] >= 0 && L_index[0] <= 169);
+ }
+
+ if (st1_mode == 2)
+ {
+ envelope_bits = 10;
+ memcpy(st1_vector, st1_vectorC, sizeof(LC3_FLOAT)*M);
+ assert(L_index[0] >= 170 && L_index[0] < 2 * 170);
+ }
+
+ L_index[1] = -910; /* aux */
+ L_index[2] = -envelope_bits; /* signal shape */
+
+ }
+ /* only run stage 2 when necessary */
+
+ {
+ LC3_FLOAT mse_lim_smooth;
+ mse_lim_smooth = (5.41); /* 1.75 SD */
+
+ mse_st1B_st2 = 2.0* min_mse_saveBCA + 1.0; /* indicate that st1B+st2 is not used by setting a higher MSE than st1BCA */
+
+ if (min_mse_saveBCA > mse_lim_smooth)
+ {
+ /* run and evaluate STAGE 2, using vector B as stage 1 */
+ for (i = 0; i < M; i++)
+ {
+ pvq_target_pre[i] = env[i] - st1_vectorB[i];
+ }
+
+ dct2_apply(&dct2structSNS, pvq_target_pre, pvq_target);
+
+ pvq_target[0] = 0.0; /* DC always zero */
+
+ fix_shape_idx = -1;
+ pvq_fess_enc_search(pvq_target, y, &fix_shape_idx); /* best shape search splitLF, full, best_fess_env */
+
+ assert(y[0][0] == 0 && y[1][0] == 0 && y[2][0] == 0);
+ lrsns_quant_shape_gain(pvq_target, y, &gain_idx, &shape, stage2_en1_norm_pre_sub, &scfq_gain, 2 + 1);
+
+ if (shape == 2)
+ {
+ shape = 2 + fix_shape_idx;
+ }
+
+ /* check if MSE after stage 2 is better already here in dct domain, avoid unnecessary IDCT-II calls */
+ envq_st1B_st2[0] = 0;
+ for (i = 1; i < M; i++)
+ {
+ envq_st1B_st2[i] = (stage2_en1_norm_pre_sub[i] * scfq_gain);
+ }
+
+ mse_st1B_st2_dct_domain = calc_mse(pvq_target, envq_st1B_st2, 1.0f, M);
+
+ if (min_mse_saveBCA < mse_st1B_st2_dct_domain)
+ {
+ /* no need for an IDCT as stage2 was worse than only stage1 */
+ mse_st1B_st2 = mse_st1B_st2_dct_domain;
+ }
+ else
+ {
+ /* Inverse transform */
+ idct_II(stage2_en1_norm_pre_sub, stage2_en1_norm_sub, M);
+
+ for (i = 0; i < M; i++)
+ {
+ envq_st1B_st2[i] = st1_vectorB[i] + (stage2_en1_norm_sub[i] * scfq_gain);
+ }
+ mse_st1B_st2 = calc_mse(env, envq_st1B_st2, 1.0f, M);
+ }
+ }
+ } /*end of stage2 search */
+
+ /* post-evaluate if one of (st1B, st1C, st1A) was actually better than st1B+stage2 */
+ if (mse_st1B_st2 < min_mse_saveBCA)
+ { /* use stage1B + st2 at 29b/30b bits total */
+ L_index[0] = ind_saveB;
+ L_index[1] = 2930; /* later stage2 aux value LS_splitLF or LS_full or s0, put here as a 0 or 1 */
+ L_index[2] = shape; /* 0=splitLF, 1=full, ( 2=fixEnv0, 3=fixEnv1, 4: fixEnv2, 5: fixEnv3 ) */
+ L_index[3] = gain_idx; /* gain_idx with a shape dependent number of levels (4 or 8 levels ) */
+
+ memcpy(envq, envq_st1B_st2, sizeof(LC3_FLOAT)*M);
+ memcpy(st1_vector, st1_vectorB, sizeof(LC3_FLOAT)*M); /* save final st1B result, st1 in combination with stage 2, for verification */
+ envelope_bits = 29; /* 'LR_splitLF' */
+ if (shape > 0)
+ {
+ envelope_bits += 1; /*30 'LR_full/LR_fixenv' */
+ }
+
+ {
+ /* DBG check values */
+ assert(shape >= 0);
+ assert(envelope_bits >= 29);
+ assert(L_index[0] <= 170); /*only B allowed */
+ assert(L_index[1] >= 0);
+
+ assert(gain_idx >= 0); /*index*/
+ assert(scfq_gain > 0.0); /* value */
+ }
+ }
+ else
+ { /* stick to stage1(best of BCA) at 9 or 10 bits */
+ assert(L_index[1] < 0 && L_index[0] >= 0 && L_index[0] < 512);
+ envelope_bits = ((L_index[0] >= 510) ? 9 : 10);
+ shape = -envelope_bits; /* signal an invalid shape number to enc-entropy */
+
+ memcpy(envq, st1_vector, M * sizeof(LC3_FLOAT)); /* output */
+ memset(stage2_en1_norm_sub, 0, M * sizeof(*stage2_en1_norm_sub));
+ scfq_gain = 0.0f;
+ gain_idx = -1; /* L_index sentinel */
+ L_index[2] = shape;
+ }
+
+ /******************************************************************/
+ /* signal to enc_entropy for LRSNS semi-fractional multiplexing */
+ /******************************************************************/
+ /* integer multiplexing 29/30 bit modes into intermediate unmuxed integer indeces 0...7 */
+ /* a bit of fractional multiplexing for these indeces 0...7 is done later, in function enc_entropy() */
+ if (shape >= 0)
+ { /* stage 2 multiplexing manipulations */
+
+
+ if (shape == 0)
+ { /* splitLF */
+ LC3_INT32 n5k = 0;
+ for (i = 0; i < 5; i++)
+ {
+ n5k += abs(y[shape][1 + i]);
+ }
+
+ if (n5k == 6)
+ {
+ MPVQ_enum(5, &(y[shape][1]), &(L_index[4]), &LS_tmp_ind); /* P(N=5,K=6) (10)=10 bit L_index */
+ L_index[1] = LS_tmp_ind; /* set the aux bit for the splitLF path, plant the first LS as aux */
+ assert((L_index[4] >= 0) && (L_index[4] < (SNSLR_NPVQ_L5K6 >> 1)));
+
+ MPVQ_enum(8, &(y[shape][1 + 5]), &(L_index[5]), &LS_tmp_ind);
+ L_index[5] = (L_index[5] << 1) + LS_tmp_ind; /* A full PVQ 7 bit index for the P(N=8,K=2) B config*/
+ assert((L_index[5] >= 0) && (L_index[5] < (1 << 7)));
+ }
+ else
+ {
+ MPVQ_enum(5, &(y[shape][1]), &(L_index[4]), &LS_tmp_ind); /* PVQ(N=5,K=8) (12.x in total, i.e. LS+ 11.x ) */
+ L_index[1] = LS_tmp_ind; /* aux bit for the splitLF path , plant the first LS as aux */
+ assert((L_index[4] >= 0) && (L_index[4] < (SNSLR_NPVQ_L5K8 >> 1)));
+ L_index[5] = -8; /* signal LF PVQ(5,8) and zeroed HF(10,0) */
+ }
+ }
+ if (shape == 1)
+ { /* full (15,5) , LS kept separated */
+ /* indicate a stage2 path in the 9 bit stage1 index */
+ MPVQ_enum(15, &(y[shape][1]), &(L_index[4]), &LS_tmp_ind); /* mPVQ 16.66 bits in index[4], and LS 1 bit in index[1] */
+ L_index[1] = LS_tmp_ind; /*aux bit location, 0 or 1 , we plant the LS there */
+ assert((L_index[4] >= 0) && (L_index[4] < (SNSLR_NPVQ_L15K5 >> 1)));
+ }
+ if (shape >= 2 && shape <= 5)
+ {
+ /* fixEnv0, fixEnv1, fixEnv2, fixEnv3 */
+ /* send the fixed env subshape mode to enc_entropy */
+ L_index[4] = (shape - 2); /* env shape, 0-->"1" , 1--> "env1" */ /* L_index[2] has original shape 0...5 */
+
+ shape_local = 2; /*a single y shape vector for all fixed env */
+
+ fix_shift_ind = 0;
+ while (y[shape_local][1 + fix_shift_ind] == 0)
+ {
+ fix_shift_ind += 1;
+ }
+ fix_shift_bits = 2;
+
+ assert(fix_shift_ind < (1 << fix_shift_bits));
+
+ L_index[1] = (y[shape_local][1 + fix_shift_ind /* + 0*/] < 0); /* aux_bit : 0 (or 1) , will indicate the s0 sign in the FESS fix shape */
+
+
+ fix_end_sign = 12;
+ if (shape == 5)
+ {
+ assert(L_index[4] == 3);
+ fix_end_sign = (fix_end_sign - 2); /* shape 4 has 2 bits shift and a total of 10 signs =2^10*2^2 = 2^12 = 4096 */
+ }
+
+ L_index[5] = fix_shift_ind; /* the two shift bits will be pushed up to b11,b12 , for 11 signs s1-s11 */
+
+ for (int sign_ind = 1; sign_ind < fix_end_sign; sign_ind++) /* push the remaining sequential signs s1-s11(or s1-s9), into a single idx */
+ { /* s1 is in the MSB, and s11 is in the lsb*/
+ L_index[5] = L_index[5] << 1;
+ if (y[shape_local][1 + fix_shift_ind + sign_ind] < 0) /*"1" means negative, "0" means positive */
+ {
+ L_index[5] += 1;
+ }
+ }
+ assert(L_index[5] >= 0 && L_index[5] < (1 << (fix_shift_bits + (fix_end_sign - 1))));
+ }
+ } /* end of stage2 premultiplexing */
+
+ {
+ assert(envelope_bits == 9 || envelope_bits == 10 || envelope_bits == 29 || envelope_bits == 30);
+ }
+
+ return envelope_bits;
+}
+
+void FESSdeenum(LC3_UINT8 dim_in, /* i : dimension of vec_out */
+ LC3_UINT8 n_env, /* i : number of envelopes */
+ LC3_UINT8 n_shift, /* i : number shifts */
+ LC3_UINT8 n_signs, /* i : number signs */
+ LC3_INT32 env_ind, /* i:indx */
+ LC3_INT32 shift_ind, /* i:indx */
+ LC3_INT32 sign_ind, /* i:indx */
+ LC3_INT32* vec_out /* o : FESS integer pulse train */)
+{
+
+ LC3_INT32 i;
+ LC3_INT32 sign_val;
+
+ assert(n_env >= 1 && n_env <= 4);
+ assert(env_ind >= 0 && env_ind < n_env);
+ assert(shift_ind >= 0 && shift_ind < n_shift);
+
+ UNUSED(n_env);
+ UNUSED(n_shift);
+ memset(vec_out, 0, sizeof(*vec_out)*dim_in);
+
+ for (i = (shift_ind + n_signs - 1); i >= shift_ind; i--)
+ {
+ /* low numbered coeff signs are in the msb's */
+ /* high numbered coeff signs are in the lsb's */
+ assert(i < dim_in);
+ sign_val = 1 - 2 * (sign_ind & 0x01);
+ sign_ind = (sign_ind >> 1);
+ vec_out[i] = sign_val * env_ptrs[env_ind][i]; /* vec_out[i] = sign_val * amps[env_ind*(M - 1) + i]; */
+ }
+}
+
+void snsQuantScfDecLR(LC3_INT32* sns_vq_idx, LC3_FLOAT* scf_q, LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx)
+{
+ LC3_INT32 i;
+ LC3_INT32 mPVQ_ind; /* can be 16-17 bits */
+ LC3_INT16 shape_idx, gain_idx, cb_idx, aux_idx, LS_ind;
+ LC3_INT16 env_ind, shift_ind, sign_ind, n_signs;
+
+ LC3_INT32 Y_shape_j[M];
+ LC3_FLOAT Xq_shape_j[M], Xq_shape_j_idct[M], sum;
+ const LC3_FLOAT *cb;
+ const LC3_FLOAT *gainTab;
+ LC3_FLOAT st1_scf_q[M];
+ LC3_INT16 CBCmeanp_ind = pitch_rx; /* 0 or 1 */
+ const LC3_FLOAT *mean_cb;
+ LC3_INT16 sign_mask = 0x07ff;
+
+
+#ifdef LRSNS_CBC_NO_LTPF_DEPENDENCY
+ UNUSED(ltpf_rx);
+#endif
+
+ sum = 0;
+ memset(Y_shape_j, 0, sizeof(LC3_INT32) * M);
+
+ gainTab = &(lrsns_gains_Q11[0][0]); /* gcc warning init */
+ gain_idx = 0; /* gcc warning init */
+
+ cb_idx = sns_vq_idx[0];
+ aux_idx = sns_vq_idx[1];
+ shape_idx = sns_vq_idx[2]; /* analysis order shape idx -9,-10, 0,1, 2,3,4,5 */
+ gain_idx = sns_vq_idx[3]; /* stage 2 gain */
+
+ /* Stage1 cand */
+ if (shape_idx == -9)
+ {
+ /* minminal 2*16 SNS codebook, no DC */
+ cb = lrsns_st1A_topTab_1bitNoDC;
+ memcpy(scf_q, &(cb[cb_idx * M]), sizeof(LC3_FLOAT) * M);
+ }
+ else if (shape_idx == -10)
+ { /* 0..339 */ /* stage 1 only, transmitted in 9+1= 10 bits */
+ if (cb_idx < 170)
+ { /*Stage 1B */
+ snslr_st1B_vector_dec(cb_idx, st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, lrsns_st1B_merged170orderSortedSegmCum, lrsns_st1B_merged170orderSort12bitIdx, scf_q);
+ snslr_remove_st1_DC_fQ11(scf_q, M);
+ }
+ else
+ {
+ cb_idx -= 170;
+ /* Stage 1C harm outlier CB with a pitch dependent mean */
+ /* Q11 values , so that BASOP and float always becomes BE in synthesis*/
+ assert(cb_idx >= 0 && cb_idx < 170);
+ snslr_st1C_vector_dec(cb_idx, lrsns_st1C_Both_Word8, lrsns_st1C_Both_scaleQ4_7p4bits_fx[1], lrsns_st1C_Both_inv_scaleQ15_7p4bits_fx[1],
+ M, 170, scf_q
+ );
+
+
+ /* cbC add harmonic mean , based on pitch_info availability */
+ pitch_rx = sns_vq_idx[3]; /* LTP active flag directly from dec_entropy */
+#ifdef LRSNS_CBC_NO_LTPF_DEPENDENCY
+ ltpf_rx = 0; /* CB_C has no dependency on LTPF active flag */
+#else
+ ltpf_rx = sns_vq_idx[4]; /* LTPF active flag LTP active flag directly from dec_entropy */
+#endif
+ CBCmeanp_ind = pitch_rx; /* 0 or 1 */
+#ifndef LRSNS_CBC_NO_LTPF_DEPENDENCY
+ if (pitch_rx != 0 && ltpf_rx != 0)
+ {
+ CBCmeanp_ind = CBCmeanp_ind + 1; /* high corr ltpf_rx is also active */
+ }
+#endif
+
+ mean_cb = lrsns_st1CTrainedMapMeans[CBCmeanp_ind]; /* point to pitch dependent mean */
+ for (i = 0; i < M; i++)
+ {
+ scf_q[i] += mean_cb[i];
+ }
+ /* remove_DC() call is not required for section C */
+ /* a very small DC can still exist though, due to Q7+Q4 quantization of values */
+ }
+ }
+ else
+ { /* 0...169 */ /* st1B* used with a stage 2 shape submode */
+ assert(shape_idx >= 0);
+ snslr_st1B_vector_dec(cb_idx, st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, lrsns_st1B_merged170orderSortedSegmCum, lrsns_st1B_merged170orderSort12bitIdx, scf_q);
+ snslr_remove_st1_DC_fQ11(scf_q, M); /* DC needs removal for st1 part B */
+ }
+ memcpy(st1_scf_q, scf_q, sizeof(LC3_FLOAT) * M); /* keep track of stage 1 contribution */
+
+ if (shape_idx >= 0) /* stage 2 shapes 0,1, 2,3,4,5 ( negative idx used for stage1 only */
+ {
+ /* Stage 2 SNS VQ decoding */
+ /* Decode shape_j */
+ Y_shape_j[0] = 0; /* no DCT-II DC-coeff decoded */
+
+ switch (shape_idx)
+ {
+ case 0: /* splitLF 29 bits total */
+ LS_ind = aux_idx;
+ mPVQ_ind = sns_vq_idx[4]; /* mPVQ(5,6) or mPVQ(5,8) */
+
+ if (sns_vq_idx[5] >= 0)
+ {
+ MPVQdeenum(5, 6, LS_ind, mPVQ_ind, &Y_shape_j[1]);
+ LS_ind = sns_vq_idx[5] & 0x1;
+ mPVQ_ind = sns_vq_idx[5] >> 1;
+ MPVQdeenum(8, 2, LS_ind, mPVQ_ind, &Y_shape_j[1 + 5]);
+ }
+ else
+ {
+ MPVQdeenum(5, 8, LS_ind, mPVQ_ind, &Y_shape_j[1]);
+ }
+ gainTab = &(lrsns_gains_Q11[0][0]);/* 4 levels in 2 bits */
+
+ break;
+ case 1: /* full 30 bits total */
+ LS_ind = aux_idx;
+ mPVQ_ind = sns_vq_idx[4];
+ MPVQdeenum(15, 5, LS_ind, mPVQ_ind, &Y_shape_j[1]);
+ gainTab = &(lrsns_gains_Q11[1][0]); /* 8 levels in 3 bits */
+
+ break;
+ case 2: /* fix env 0 , init_bell 12 signs */
+ case 3: /* fix env 1 , decay 24-->13 12 signs */
+ case 4: /* fix env 2 , start bell 12 signs */
+ case 5: /* fix env 3 , early bell 10 signs */
+ LS_ind = aux_idx; /* s0 */
+ env_ind = sns_vq_idx[4];
+ assert(env_ind == (shape_idx - 2));
+
+ n_signs = 12; /* including s0 */
+ if (env_ind == 3) {
+ n_signs -= 2;
+ }
+ sign_mask = (sign_mask >> (12 - n_signs));
+
+ shift_ind = sns_vq_idx[5] >> (n_signs - 1);
+ sign_ind = sns_vq_idx[5] & sign_mask;
+
+ /* put s0 , right next to s1 , to make the sign decoding loop easier */
+ sign_ind = (sign_ind)+(LS_ind << (n_signs - 1)); /* s0 put as MSB at 12th position 2^11 , lsb at 2^0 */
+
+ /*FixEnvShiftSigns deenumeration */
+ FESSdeenum(15, 4, 4, n_signs, env_ind, shift_ind, sign_ind, &Y_shape_j[1]); /*30b , 4xenv,4xshifts, 10 or12 signs, over 15 positions,*/
+ gainTab = &(lrsns_gains_Q11[2][0]);; /* 8 levels in 3 bits */
+ /* fix_envshift_nb = env_ind * 4 + shift_ind; */ /* index for fast normalization lookup */
+ break;
+ default:
+
+ break;
+ }
+
+ /* Unit energy normalization of the received shape */
+ for (i = 0; i < M; i++)
+ {
+ sum += (Y_shape_j[i] * Y_shape_j[i]);
+ }
+
+ sum = 1.0 / LC3_SQRT(sum); /* all shapes will have tabled inv_sqrt() divisions as factors in BASOP */
+
+ for (i = 0; i < M; i++)
+ {
+ Xq_shape_j[i] = Y_shape_j[i] * sum;
+ }
+
+ /* Reconstruction of the quantized SNS scale factors */
+ idct_II(Xq_shape_j, Xq_shape_j_idct, M);
+ for (i = 0; i < M; i++) {
+ scf_q[i] += Xq_shape_j_idct[i] * gainTab[gain_idx];
+ }
+ }
+ else
+ { /* -9, -10 */
+ /* LRSNS stage 1 variations only */
+ memcpy(scf_q, st1_scf_q, sizeof(LC3_FLOAT) * M);
+ }
+}
+
+/* LRSNS integer precision based function needed in both encoder and decoder */
+LC3_FLOAT snslr_remove_st1_DC_fQ11(LC3_FLOAT *scfq, LC3_INT32 len)
+{
+ LC3_INT32 i; /*Counter*/
+ LC3_INT32 L_dcQ11;
+ LC3_FLOAT f_dcQ11 = 0.0;
+ L_dcQ11 = 0L;
+
+ for (i = 0; i < len; i++) {
+ L_dcQ11 += (LC3_INT32)(scfq[i] * 2048.0f); /* BE simulation of DC Q11 summation of truncated values in BASOP, preferably BE in synthesis in FLP/BASOP decoder */
+ }
+
+ assert(len == M);
+ {
+ L_dcQ11 = L_dcQ11 >> 4; /* make the average in integer domain , no rounding applied before shift, on purpose */
+ f_dcQ11 = ((LC3_FLOAT)L_dcQ11) *(1.0f / 2048.0f); /* now a Q11 value to match the overall generic Q11 BASOP scaling of stage1 variables */
+ }
+
+ for (i = 0; i < len; i++)
+ {
+ scfq[i] -= f_dcQ11; /* result update */
+ }
+ return f_dcQ11; /* output used for encoder side mse update*/
+}
+
+#endif
diff --git a/lib_lc3plus/structs.h b/lib_lc3plus/structs.h
index 357531c3e89683efde5ec7e3c12d1b62774008f7..b446c3a201732c65543c6fb4465cc6c0373c2e97 100644
--- a/lib_lc3plus/structs.h
+++ b/lib_lc3plus/structs.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -195,6 +195,9 @@ typedef struct {
LC3_INT16 overall_counter;
LC3_INT8 longterm_counter_byte_position;
LC3_INT8 longterm_counter_bit_position;
+#ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
+ LC3_INT16 numberOfGoodFrames;
+#endif
} PlcAdvSetup;
#endif
diff --git a/lib_lc3plus/tns_coder.c b/lib_lc3plus/tns_coder.c
index 9e3c3f6f206cd9ea92490640072bc4a476de82d6..3dbd1e9aa0564149b753eca6d9066a47ed43ebbf 100644
--- a/lib_lc3plus/tns_coder.c
+++ b/lib_lc3plus/tns_coder.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
@@ -142,7 +142,7 @@ void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len)
}
-void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3_INT frame_dms, LC3_INT nBits,
+void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3PLUS_FrameDuration frame_dms, LC3_INT nBits,
LC3_INT* order_out, LC3_INT* rc_idx, LC3_INT* tns_numfilters, LC3_INT* bits_out
, LC3_INT16 near_nyquist_flag
)
@@ -159,16 +159,15 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L
/* Init */
- if (fs >= 32000 && frame_dms >= 50) {
+ if (fs >= 32000 && frame_dms >= LC3PLUS_FRAME_DURATION_5MS) {
numfilters = 2;
} else {
numfilters = 1;
}
/* 40 * frame_dms / 10 = 4 * frame_dms */
- if (N > 4 * frame_dms)
- {
- N = 4 * frame_dms;
+ if (N > 40 * ((LC3_FLOAT) (frame_dms*1.25*10) / 10.0)) {
+ N = 40 * ((LC3_FLOAT) (frame_dms*1.25*10) / 10.0);
fs = 40000;
}
@@ -184,27 +183,35 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L
switch (frame_dms)
{
- case 25:
+#ifdef CR9_C_ADD_1p25MS
+ case LC3PLUS_FRAME_DURATION_1p25MS:
+ maxOrder = 4;
+ nSubdivisions = 2.0;
+ break;
+#endif
+ case LC3PLUS_FRAME_DURATION_2p5MS:
maxOrder = 4;
nSubdivisions = 2.0;
break;
- case 50:
+ case LC3PLUS_FRAME_DURATION_5MS:
maxOrder = 4;
nSubdivisions = 2.0;
break;
- case 75:
+ case LC3PLUS_FRAME_DURATION_7p5MS:
maxOrder = 8;
nSubdivisions = 3;
break;
- case 100:
+ case LC3PLUS_FRAME_DURATION_10MS:
maxOrder = 8;
nSubdivisions = 3.0;
break;
+ case LC3PLUS_FRAME_DURATION_UNDEFINED:
+ assert(0);
}
minPredictionGain = 1.5;
- if (nBits >= 4.8 * frame_dms) {
+ if (nBits >= 4.8 * ((LC3_FLOAT) frame_dms * 1.25 * 10)) {
order = order1_tns;
} else {
order = order2_tns;
@@ -293,7 +300,7 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L
if (tns == 1) {
minPGfac = 0.85;
maxPG = 2;
- if (nBits >= 4.8 * frame_dms) {
+ if (nBits >= 4.8 * frame_dms*1.25*10) {
maxPG = minPredictionGain;
}
@@ -335,11 +342,11 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L
order_out[f] = order_tmp;
- // Disable TNS if order is 0:
+ /* Disable TNS if order is 0: */
if (order_out[f] == 0) {
tns = 0;
- // Jump to else statement
+ /* Jump to else statement */
goto tns_disabled;
}
tmp = order[order_out[f] - 1];
diff --git a/lib_lc3plus/tns_decoder.c b/lib_lc3plus/tns_decoder.c
index 05f8036fc4b99ed64a92e78eb44477adf60806a2..37e831d464c5ecc031056fb276beba5c346788a6 100644
--- a/lib_lc3plus/tns_decoder.c
+++ b/lib_lc3plus/tns_decoder.c
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
diff --git a/lib_lc3plus/util.h b/lib_lc3plus/util.h
index 410b7db44b02527da3d2123816a82ff2a264909c..05fd54467bc93375ba1c8abdba8bb9e848b18f70 100644
--- a/lib_lc3plus/util.h
+++ b/lib_lc3plus/util.h
@@ -1,5 +1,5 @@
/******************************************************************************
-* ETSI TS 103 634 V1.5.1 *
+* ETSI TS 103 634 V1.6.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *