diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 26d844b25790df713649724770d84602cade342c..eef6803ede6f8e58641973634c92165f257d47d0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1060,7 +1060,7 @@ check-first-frame-is-sid: expose_as: "logs-sidstart" expire_in: "5 days" -lc3plus-ensure-no-code-changes: +.lc3plus-ensure-no-code-changes: extends: - .test-job-linux - .rules-merge-request-to-main diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj index 3f1527357ad6c96d8629a85f7ab3937e82fb3bb0..7b434ae10a13c7d2fe1385b28d941bb484f63b75 100644 --- a/Workspace_msvc/lib_lc3plus.vcxproj +++ b/Workspace_msvc/lib_lc3plus.vcxproj @@ -107,6 +107,7 @@ + diff --git a/lib_isar/isar_lc3plus_common.c b/lib_isar/isar_lc3plus_common.c index a186908990ca5366ef81bb6e5a5b53c8726eb6fc..f7fe0db32ebeba38eeec378a57c47154a8031046 100644 --- a/lib_isar/isar_lc3plus_common.c +++ b/lib_isar/isar_lc3plus_common.c @@ -92,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 eb3e7b0ad2d7d245c046cd7fc7699d7a178b8b78..3b52e5b3f15c0ce29c25f7d640140530db05afb6 100644 --- a/lib_isar/isar_lc3plus_common.h +++ b/lib_isar/isar_lc3plus_common.h @@ -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 c5d78f444684b1433894114ea9f1377ee9a49e4b..0455144381e2b9cf8f8f30b55b53841dbe4a2246 100644 --- a/lib_isar/isar_lc3plus_dec.c +++ b/lib_isar/isar_lc3plus_dec.c @@ -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_enc.c b/lib_isar/isar_lc3plus_enc.c index c6e2d31334271169367f7f0695806256a7f4c049..4be070b95778c1be5796d5a6a5d434d40d3b556d 100644 --- a/lib_isar/isar_lc3plus_enc.c +++ b/lib_isar/isar_lc3plus_enc.c @@ -168,7 +168,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_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/com_entropy.c b/lib_lc3plus/com_entropy.c new file mode 100644 index 0000000000000000000000000000000000000000..da7ee8edaa89db77882e811c08dbdbc4de5355dd --- /dev/null +++ b/lib_lc3plus/com_entropy.c @@ -0,0 +1,29 @@ +/****************************************************************************** +* 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_INT16 getLastNzBits (LC3_INT16 N) +{ + 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) + { + minBits++; + } +#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 a2f4857b2ae4a3d10511b5e08249d95a73634be4..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 * @@ -21,6 +21,30 @@ #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/lc3plus.c b/lib_lc3plus/lc3plus.c index d208cfb1512bfd8a028e01bca5b8db1bfa0efbfa..594683cd2c7ea80bec716871779ed4e1b0d8b0e1 100644 --- a/lib_lc3plus/lc3plus.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 * @@ -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/lc3plus.h b/lib_lc3plus/lc3plus.h index 063714467da07d43f63d214cbfcec5eb13ff507c..955e22fe78a70c5b79259a176a38621b0fa266d3 100644 --- a/lib_lc3plus/lc3plus.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 * @@ -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 index f37af56a3109e415bed3f7d2d49507c99ffa5bed..055b6a0047f7a769857550a7e4fab9ad5a4c3022 100644 --- a/lib_lc3plus/setup_com_lc3plus.c +++ b/lib_lc3plus/setup_com_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 * @@ -11,6 +11,30 @@ #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; diff --git a/lib_lc3plus/setup_dec_lc3plus.c b/lib_lc3plus/setup_dec_lc3plus.c index 9e9a5ea64e021c3669e4b439ac19bd22f9f1c43c..67a86bb027eb4a3076f539305382696034b69da4 100644 --- a/lib_lc3plus/setup_dec_lc3plus.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 * @@ -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_lc3plus.h b/lib_lc3plus/setup_dec_lc3plus.h index c3d26ee8ebe8f0b9ab46380ed6d620d7577ee9d3..5dd3e676136aa9b5e94bb12725306aec94f3382c 100644 --- a/lib_lc3plus/setup_dec_lc3plus.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_lc3plus.c b/lib_lc3plus/setup_enc_lc3plus.c index 80bd909ab3268179e74cc61bf9c09e5223c570dc..438a721d061ee358695a07e550a8a641e15f535b 100644 --- a/lib_lc3plus/setup_enc_lc3plus.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 * @@ -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_lc3plus.h b/lib_lc3plus/setup_enc_lc3plus.h index 7947a0e649dc352909a54ff500c9165082f02763..1f1656f36510afc6ff44c0300c20e49981543fcb 100644 --- a/lib_lc3plus/setup_enc_lc3plus.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 * diff --git a/scripts/lc3plus_lib_setup/get_lc3plus.sh b/scripts/lc3plus_lib_setup/get_lc3plus.sh index f654768707921d45b2f6cbfbe90881cc6a528649..1aa5dc7b3a28110ec744577f1392033d250ebe0d 100755 --- a/scripts/lc3plus_lib_setup/get_lc3plus.sh +++ b/scripts/lc3plus_lib_setup/get_lc3plus.sh @@ -3,45 +3,36 @@ # This script shall only be used by automated continuous integration systems printf "Cleaning old version of LC3plus\n" -rm -rf lib_lc3plus +rm -rf lib_lc3plus/* printf "Downloading LC3plus code\n" -if true; then - # Waiting for official ETSI release. - # TODO: add new URL, remove `if false` when package goes public - curl -o ./lc3plus_sources.zip https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.05.01_60/ts_103634v010501p0.zip - unzip lc3plus_sources.zip -d . - rm lc3plus_sources.zip - cp -r "ETSI_Release/LC3plus_ETSI_src_v5f640bd48cc_20240516/src/floating_point" lib_lc3plus - rm -r ETSI_Release -else - # Temp solution for downloading WIP ETSI package - # LC3_ETSI_REPO_URL must be define before running the script - git clone "$LC3_ETSI_REPO_URL" - cp -r lc3_etsi_release/src/floating_point lib_lc3plus - rm -rf lc3_etsi_release -fi + +curl -o ./lc3plus_sources.zip https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.06.01_60/ts_103634v010601p0.zip +unzip -o lc3plus_sources.zip -d . -x "__MACOSX/*" "package.info" +rm lc3plus_sources.zip +cp -r LC3plus_ETSI_src_v527e88bdddb_20251022/src/floating_point/* lib_lc3plus +rm -r LC3plus_ETSI_src_v527e88bdddb_20251022 # Remove unneeded files printf "Removing unneeded files\n" -rm lib_lc3plus/codec_exe.c # Only used for executable -rm lib_lc3plus/makefile # Build handled at IVAS level -rm -r lib_lc3plus/msvc # Build handled at IVAS level +rm lib_lc3plus/codec_exe.c # Only used for executable +rm lib_lc3plus/makefile # Build handled at IVAS level +rm -r lib_lc3plus/msvc # Build handled at IVAS level rm lib_lc3plus/plc_noise_substitution0.c # Empty file -rm lib_lc3plus/tinywavein_c.h # Only used for executable -rm lib_lc3plus/tinywaveout_c.h # Only used for executable +rm lib_lc3plus/tinywavein_c.h # Only used for executable +rm lib_lc3plus/tinywaveout_c.h # Only used for executable # Limit file permissions printf "Limiting file permissions\n" -find lib_lc3plus -type f -print0 | \ -xargs -0 -I {} \ -chmod -x {} +find lib_lc3plus -type f -print0 | + xargs -0 -I {} \ + chmod -x {} # include options.h in all C files printf "Including options.h and wmc_auto.h in C files\n" -find lib_lc3plus -name '*.[ch]' -type f -print0 | \ -xargs -0 -I {} \ -sed -i ' +find lib_lc3plus -name '*.[ch]' -type f -print0 | + xargs -0 -I {} \ + sed -i ' # range: from 1st line to first match 1,/^#include/ { # insert lines before first match @@ -53,17 +44,18 @@ sed -i ' # Remove whitespace from preprocessor commands printf "Removing whitespace from preprocessor commands\n" -find lib_lc3plus -name '*.[ch]' -type f -print0 | \ -xargs -0 -I {} \ -sed -i 's/^#[[:space:]]\+/#/' {} +find lib_lc3plus -name '*.[ch]' -type f -print0 | + xargs -0 -I {} sh -c ' + sed -i "s/^#[[:space:]]\+/#/" "$1" + sed -i "s/^#\(define\|undef\|ifdef\|ifndef\|endif\|if\|else\|elif\|include\)[[:space:]]\+/#\1 /" "$1" + ' _ {} -# fix for sanitizer issues -sed -i 's/st->low << 8/(LC3_INT)((LC3_UINT32)st->low << 8)/' lib_lc3plus/ari_codec.c -sed -i 's/~3/(uintptr_t)(~3)/' lib_lc3plus/lc3plus.c +# delete define of NPRM_RESQ - not used anywhere in LC3plus but conflicts with IVAS +sed -i '/^\/\* RESIDUAL CODING \*\/$/d; /^#define NPRM_RESQ 5 \* MAX_LEN$/d' lib_lc3plus/defines.h # Add .clang-format file to lib_lc3plus to disable formatting there printf "Disabling clang-format in lib_lc3plus directory\n" printf ' DisableFormat: true SortIncludes: Never -' >> lib_lc3plus/.clang-format +' >lib_lc3plus/.clang-format diff --git a/scripts/lc3plus_lib_setup/get_lc3plus_fx.sh b/scripts/lc3plus_lib_setup/get_lc3plus_fx.sh new file mode 100644 index 0000000000000000000000000000000000000000..389fe76cadaa509c0472a09e5c5280344ed2219f --- /dev/null +++ b/scripts/lc3plus_lib_setup/get_lc3plus_fx.sh @@ -0,0 +1,174 @@ +#!/usr/bin/env bash + +# This script shall only be used by automated continuous integration systems + +set -ux + +printf "Cleaning old version of LC3plus\n" +rm -rf lib_lc3plus/* + +printf "Downloading LC3plus code\n" + +curl -o ./lc3plus_sources.zip https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.06.01_60/ts_103634v010601p0.zip +unzip -o lc3plus_sources.zip -d . -x "__MACOSX/*" "package.info" +rm lc3plus_sources.zip +cp -r LC3plus_ETSI_src_v527e88bdddb_20251022/src/fixed_point/* lib_lc3plus +rm -r LC3plus_ETSI_src_v527e88bdddb_20251022 + +cd lib_lc3plus + +printf "Updating LC3plus code for IVAS BASOP compatibility\n" + +# rename files +mv basic_op/dynmem.[ch] . +mv basop_mpy.c basop_mpy_lc3plus.c +mv basop_mpy.h basop_mpy_lc3plus.h +mv basop_util.c basop_util_lc3plus.c +mv basop_util.h basop_util_lc3plus.h +mv fft.c fft_lc3plus.c +mv rom_basop_util.c rom_basop_util_lc3plus.c +mv rom_basop_util.h rom_basop_util_lc3plus.h + +# remove unneeded files +rm makefile +rm codec_exe.c +rm ccConvert.c +rm tinywavein_c.h +rm tinywaveout_c.h +rm -r basic_op +rm -r msvc +rm -r msvc_ccc + +# update header include guards to avoid conflict +sed -i 's|__BASOP_UTIL_H__|__BASOP_UTIL_LC3PLUS_H__|g' basop_util_lc3plus.h +sed -i 's|__BASOP_UTIL_ROM_H__|__BASOP_UTIL_ROM_LC3PLUS_H__|g' rom_basop_util_lc3plus.h + +# update includes for renamed files +sed -i 's|#include "basop_mpy.h"|#include "basop_mpy_lc3plus.h"|g' *.[ch] +sed -i 's|#include "basop_util.h"|#include "basop_util_lc3plus.h"|g' *.[ch] +sed -i 's|#include "rom_basop_util.h"|#include "rom_basop_util_lc3plus.h"|g' *.[ch] + +# deactivate DYNMEM_COUNT, conflicts with WMC tool +sed -i 's|#define DYNMEM_COUNT|// #define DYNMEM_COUNT /* conflicts with WMC tool */|g' defines.h + +# change BASOP_sub_start/end to push/pop_wmops wrapped in #ifdef WMOPS +sed -E -i 's|BASOP(_sub){1,2}_start|push_wmops|g' *.[ch] +sed -E -i 's|BASOP(_sub){1,2}_end|pop_wmops|g' *.[ch] +sed -E -i 's|^(.*p[uo][sp]h?_wmops.*)$|#ifdef WMOPS\n\1\n#endif|g' *.[ch] + +# rename conflicting BASOPs +sed -i 's|Isqrt|Isqrt_lc3plus|g' *.[ch] +sed -i 's|\bMpy_32_16(|Mpy_32_16_lc3plus(|g' *.[ch] +sed -i 's|\bMpy_32_32(|Mpy_32_32_lc3plus(|g' *.[ch] + +# suppress #pragma message() +sed -i 's/\#pragma message(/\/\/ \#pragma message(/g' lc3plus.c + +# add ENABLE_HR_MODE to lc3plus.h +sed -i '/\#define LC3PLUS_H/a\#define ENABLE_HR_MODE' lc3plus.h + +# add macros missing from IVAS at the bottom of the file +sed -i '/\#endif \/\* __BASOP_UTIL_LC3PLUS_H__ \*\//i\ +/* Macros missing from IVAS BASOP, used only in LC3plus */\ +#define L_shl_pos(x, y) (L_shl((x), (y)))\ +#define L_shr_pos(x, y) (L_shr((x), (y)))\ +#define L_shr_pos_pos(x, y) (L_shr((x), (y)))\ +\ +#define L_shr_r_pos(x, shift) (L_shr_r(x, shift))\ +\ +#define shl_pos(x, y) (shl((x), (y)))\ +#define shr_pos(x, y) (shr((x), (y)))\ +#define shr_pos_pos(x, y) (shr((x), (y)))\ +\ +#define lshl_pos(x, y) (lshl(x, y))\ +#define UL_lshr_pos(x, y) (UL_lshr(x, y))\ +#define UL_lshl_pos(x, y) (UL_lshl(x, y))' basop_util_lc3plus.h + +# locally redefine duplicate symbols +sed -i '/\#endif \/\* DEFINES_H \*\//i\ +#define FIX_IVAS_LC3PLUS_DUPLICATES\ +#ifdef FIX_IVAS_LC3PLUS_DUPLICATES\ +#define abs_s_sat abs_s\ +#define BASOP_cfft BASOP_cfft_lc3plus\ +#define BASOP_getTables BASOP_getTables_lc3plus\ +#define BASOP_Util_Add_Mant32Exp BASOP_Util_Add_Mant32Exp_lc3plus\ +#define BASOP_Util_Cmp_Mant32Exp BASOP_Util_Cmp_Mant32Exp_lc3plus\ +#define BASOP_Util_Divide1616_Scale BASOP_Util_Divide1616_Scale_lc3plus\ +#define BASOP_Util_Divide3216_Scale BASOP_Util_Divide3216_Scale_lc3plus\ +#define BASOP_Util_InvLog2 BASOP_Util_InvLog2_lc3plus\ +#define BASOP_Util_Log2 BASOP_Util_Log2_lc3plus\ +#define Copy_Scale_sig Copy_Scale_sig_lc3plus\ +#define exp2_tab_long exp2_tab_long_lc3plus\ +#define exp2w_tab_long exp2w_tab_long_lc3plus\ +#define exp2x_tab_long exp2x_tab_long_lc3plus\ +#define get_size_mpvq_calc_offset_fx get_size_mpvq_calc_offset_fx_lc3plus\ +#define getScaleFactor16 getScaleFactor16_lc3plus\ +#define getScaleFactor32 getScaleFactor32_lc3plus\ +#define i_mult DEPR_i_mult\ +#define Inv16 Inv16_lc3plus\ +#define InvDiffTable InvDiffTable_lc3plus\ +#define InvIntTable InvIntTable_lc3plus\ +#define InvTable InvTable_lc3plus\ +#define ISqrt16 ISqrt16_lc3plus\ +#define ISqrtDiffTable ISqrtDiffTable_lc3plus\ +#define ISqrtTable ISqrtTable_lc3plus\ +#define L_abs_sat L_abs\ +#define ldCoeff ldCoeff_lc3plus\ +#define Norm32Norm Norm32Norm_lc3plus\ +#define POW_ATT_TABLE0 POW_ATT_TABLE0_lc3plus\ +#define POW_ATT_TABLE1 POW_ATT_TABLE1_lc3plus\ +#define RotVector_320 RotVector_320_lc3plus\ +#define RotVector_480 RotVector_480_lc3plus\ +#define Scale_sig Scale_sig_lc3plus\ +#define SineTable320 SineTable320_lc3plus\ +#define SineWindow120 SineWindow120_lc3plus\ +#define SineWindow160 SineWindow160_lc3plus\ +#define SineWindow180 SineWindow180_lc3plus\ +#define SineWindow20 SineWindow20_lc3plus\ +#define SineWindow30 SineWindow30_lc3plus\ +#define SineWindow320 SineWindow320_lc3plus\ +#define SineWindow40 SineWindow40_lc3plus\ +#define SineWindow60 SineWindow60_lc3plus\ +#define SineWindow80 SineWindow80_lc3plus\ +#define Sqrt16 Sqrt16_lc3plus\ +#define SqrtDiffTable SqrtDiffTable_lc3plus\ +#define SqrtTable SqrtTable_lc3plus\ +#define Tab_esc_nb Tab_esc_nb_lc3plus\ +#define tnsAcfWindow tnsAcfWindow_lc3plus\ +#endif /* FIX_IVAS_LC3PLUS_DUPLICATES */' defines.h + +cd - + +# Limit file permissions +printf "Limiting file permissions\n" +find lib_lc3plus -type f -print0 | + xargs -0 -I {} \ + chmod -x {} + +# include options.h and wmc_auto.h in all C files +printf "Including options.h and wmc_auto.h in C files\n" +find lib_lc3plus -name '*.[ch]' -type f -print0 | + xargs -0 -I {} \ + sed -i ' +# range: from 1st line to first match +1,/^#include/ { + # insert lines before first match + /^#include/ i\ +#include "options.h"\ +#include "wmc_auto.h" +} +' {} + +# Remove whitespace from preprocessor commands +printf "Removing whitespace from preprocessor commands\n" +find lib_lc3plus -name '*.[ch]' -type f -print0 | + xargs -0 -I {} sh -c ' + sed -i "s/^#[[:space:]]\+/#/" "$1" + sed -i "s/^#\(define\|undef\|ifdef\|ifndef\|endif\|if\|else\|elif\|include\)[[:space:]]\+/#\1 /" "$1" + ' _ {} + +# Add .clang-format file to lib_lc3plus to disable formatting there +printf "Disabling clang-format in lib_lc3plus directory\n" +printf 'DisableFormat: true +SortIncludes: Never +' >lib_lc3plus/.clang-format diff --git a/scripts/prepare_instrumentation.sh b/scripts/prepare_instrumentation.sh index 3698b12b26357e1ecf4770f4d79b37a04dc7e2b9..906d85e785c19aae38b83e2f0c1949d8b173868e 100755 --- a/scripts/prepare_instrumentation.sh +++ b/scripts/prepare_instrumentation.sh @@ -156,7 +156,7 @@ if [ $ISAR -eq 1 ]; then echo " #define ENABLE_HR_MODE //#define DYNMEM_COUNT - #define CR10_A_ATTENUATION_CURVE_SELECTOR + //#define USE_LC3_OPERATORS #define SUBSET_NB #define SUBSET_WB #define SUBSET_SSWB diff --git a/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test.c b/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test.c index 7cdda5634263cb52e123897c0bf9c0215507757d..6833a90fea791ec587b585297c3d1f729ea92807 100644 --- a/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test.c +++ b/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test.c @@ -41,7 +41,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. #include "lc3plus.h" #define MAX_SAMPLES_PER_CHANNEL 960 / 4 -#define DEFAULT_BPS 256000 +#define DEFAULT_BPS 256000 #ifndef PCM_SAMPLE_TYPEDEF_DEFINED #define PCM_SAMPLE_TYPEDEF_DEFINED @@ -93,23 +93,23 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config, uint32_t bps ) uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); - int perChannelBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); - int perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / (1000*1000/config.lc3plus_frame_duration_us); - int targetOctets = bps / 8 / (1000*1000/config.isar_frame_duration_us); - printf("IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config.isar_frame_duration_us, config.lc3plus_frame_duration_us, config.channels, bps, targetOctets); - printf(" coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds); + int perChannelBitrate = lc3plus_enc_get_real_bitrate( encHandle->handles[0] ); + int perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / ( 1000 * 1000 / config.lc3plus_frame_duration_us ); + int targetOctets = bps / 8 / ( 1000 * 1000 / config.isar_frame_duration_us ); + printf( "IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config.isar_frame_duration_us, config.lc3plus_frame_duration_us, config.channels, bps, targetOctets ); + printf( " coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds ); int pfOctets = bitstreamSizePerIvasFrame - perLc3plusFrameDataBlockOctets; - int pfBps = pfOctets * 8 * (1000*1000 / config.isar_frame_duration_us); - printf(" payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets); - if(pfBps <= 0) + int pfBps = pfOctets * 8 * ( 1000 * 1000 / config.isar_frame_duration_us ); + printf( " payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets ); + if ( pfBps <= 0 ) { ISAR_LC3PLUS_ENC_Close( &encHandle ); return err; } Word16 Q_in[16]; - memset(Q_in, 0, sizeof(Q_in) ); - err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame, Q_in ); + memset( Q_in, 0, sizeof( Q_in ) ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame, Q_in ); if ( IVAS_ERR_OK != err ) { ISAR_LC3PLUS_ENC_Close( &encHandle ); @@ -218,19 +218,19 @@ static int tryOpenEncoderWithInvalidBitrate( void ) { return 1; } - limitedBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); - if(limitedBitrate != 320000) + limitedBitrate = lc3plus_enc_get_real_bitrate( encHandle->handles[0] ); + if ( limitedBitrate != 320000 ) { return 1; } - ISAR_LC3PLUS_ENC_Close(&encHandle); + ISAR_LC3PLUS_ENC_Close( &encHandle ); err = ISAR_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle ); /* setting an invalid bitrate should trigger an error - which is what we expect */ if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) { return 1; } - ISAR_LC3PLUS_ENC_Close(&encHandle); + ISAR_LC3PLUS_ENC_Close( &encHandle ); return 0; } @@ -295,13 +295,13 @@ static int tryCallEncoderApiWithInvalidParams( void ) } ISAR_LC3PLUS_ENC_Close( &invalidEncHandle ); Word16 Q_in[16]; - memset(Q_in, 0, sizeof(Q_in) ); - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out, bsSize, Q_in ) ) + memset( Q_in, 0, sizeof( Q_in ) ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out, bsSize, Q_in ) ) { return 1; } - memset(Q_in, 0, sizeof(Q_in) ); - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out, bsSize, Q_in) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out, bsSize, Q_in ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out, bsSize, Q_in ) ) + memset( Q_in, 0, sizeof( Q_in ) ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out, bsSize, Q_in ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out, bsSize, Q_in ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out, bsSize, Q_in ) ) { return 1; } @@ -448,7 +448,7 @@ static int encodeOneFrame( void ) uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); Word16 Q_in[16]; - memset(Q_in, 0, sizeof(Q_in) ); + memset( Q_in, 0, sizeof( Q_in ) ); err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out, bitstreamSizePerIvasFrame, Q_in ); if ( IVAS_ERR_OK != err ) @@ -488,8 +488,8 @@ static int encodeAndDecodeOneMonoFrame( void ) uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); Word16 Q_in[16]; - memset(Q_in, 0, sizeof(Q_in) ); - err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame, Q_in ); + memset( Q_in, 0, sizeof( Q_in ) ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame, Q_in ); if ( IVAS_ERR_OK != err ) return err; ISAR_LC3PLUS_ENC_Close( &encHandle ); @@ -582,25 +582,25 @@ static int encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz( void ) static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel( void ) { LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; - return encodeAndDecodeOneStereoFrame( config, config.channels * 82*1000 ); + return encodeAndDecodeOneStereoFrame( config, config.channels * 82 * 1000 ); } static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel( void ) { LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; - return encodeAndDecodeOneStereoFrame( config, config.channels * 98*1000 ); + return encodeAndDecodeOneStereoFrame( config, config.channels * 98 * 1000 ); } static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel( void ) { LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; - return encodeAndDecodeOneStereoFrame( config, config.channels * 126*1000 ); + return encodeAndDecodeOneStereoFrame( config, config.channels * 126 * 1000 ); } static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel( void ) { LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; - return encodeAndDecodeOneStereoFrame( config, config.channels * 800*1000 ); + return encodeAndDecodeOneStereoFrame( config, config.channels * 800 * 1000 ); } static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel( void ) @@ -633,8 +633,8 @@ int main( int argc, char *argv[] ) { - (void)argc; - (void)argv; + (void) argc; + (void) argv; int ret = 0; ret = openCloseEncoder(); if ( ret != 0 ) diff --git a/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test_payload_format.c b/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test_payload_format.c index 613441c8ac9ec8fc740fa88c0e53e6d4e953d5d0..5685dd1704cdd86f6964f11e0bc537b78b2fdf45 100644 --- a/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test_payload_format.c +++ b/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test_payload_format.c @@ -38,7 +38,6 @@ the United Nations Convention on Contracts on the International Sales of Goods. #include "isar_lc3plus_common.h" #include "options.h" -#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS /* included by ivas_lc3plus_unit_test.c */ @@ -448,4 +447,3 @@ static int run_all_payload_tests( void ) } return 0; } -#endif diff --git a/scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test.c b/scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test.c index c15f14b4ccfa6d8d0311950926fddb4c5cc0dc70..8c2f1a1495625fe68012ca0a9a358a66a8130f7d 100644 --- a/scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test.c +++ b/scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test.c @@ -41,7 +41,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. #include "lc3plus.h" #define MAX_SAMPLES_PER_CHANNEL 960 / 4 -#define DEFAULT_BPS 256000 +#define DEFAULT_BPS 256000 static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config, uint32_t bps ) { @@ -88,15 +88,15 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config, uint32_t bps ) uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); - int perChannelBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); - int perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / (1000*1000/config.lc3plus_frame_duration_us); - int targetOctets = bps / 8 / (1000*1000/config.isar_frame_duration_us); - printf("IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config.isar_frame_duration_us, config.lc3plus_frame_duration_us, config.channels, bps, targetOctets); - printf(" coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds); + int perChannelBitrate = lc3plus_enc_get_real_bitrate( encHandle->handles[0] ); + int perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / ( 1000 * 1000 / config.lc3plus_frame_duration_us ); + int targetOctets = bps / 8 / ( 1000 * 1000 / config.isar_frame_duration_us ); + printf( "IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config.isar_frame_duration_us, config.lc3plus_frame_duration_us, config.channels, bps, targetOctets ); + printf( " coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds ); int pfOctets = bitstreamSizePerIvasFrame - perLc3plusFrameDataBlockOctets; - int pfBps = pfOctets * 8 * (1000*1000 / config.isar_frame_duration_us); - printf(" payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets); - if(pfBps <= 0) + int pfBps = pfOctets * 8 * ( 1000 * 1000 / config.isar_frame_duration_us ); + printf( " payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets ); + if ( pfBps <= 0 ) { ISAR_LC3PLUS_ENC_Close( &encHandle ); return err; @@ -211,19 +211,19 @@ static int tryOpenEncoderWithInvalidBitrate( void ) { return 1; } - limitedBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); - if(limitedBitrate != 320000) + limitedBitrate = lc3plus_enc_get_real_bitrate( encHandle->handles[0] ); + if ( limitedBitrate != 320000 ) { return 1; } - ISAR_LC3PLUS_ENC_Close(&encHandle); + ISAR_LC3PLUS_ENC_Close( &encHandle ); err = ISAR_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle ); /* setting an invalid bitrate should trigger an error - which is what we expect */ if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) { return 1; } - ISAR_LC3PLUS_ENC_Close(&encHandle); + ISAR_LC3PLUS_ENC_Close( &encHandle ); return 0; } @@ -567,13 +567,13 @@ static int encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz( void ) static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel( void ) { LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; - return encodeAndDecodeOneStereoFrame( config, config.channels * 82*1000 ); + return encodeAndDecodeOneStereoFrame( config, config.channels * 82 * 1000 ); } static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel( void ) { LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; - return encodeAndDecodeOneStereoFrame( config, config.channels * 98*1000 ); + return encodeAndDecodeOneStereoFrame( config, config.channels * 98 * 1000 ); } #ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6 @@ -583,13 +583,13 @@ static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel #endif { LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; - return encodeAndDecodeOneStereoFrame( config, config.channels * 126*1000 ); + return encodeAndDecodeOneStereoFrame( config, config.channels * 126 * 1000 ); } static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel( void ) { LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; - return encodeAndDecodeOneStereoFrame( config, config.channels * 800*1000 ); + return encodeAndDecodeOneStereoFrame( config, config.channels * 800 * 1000 ); } static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel( void ) @@ -622,8 +622,8 @@ int main( int argc, char *argv[] ) { - (void)argc; - (void)argv; + (void) argc; + (void) argv; int ret = 0; ret = openCloseEncoder(); if ( ret != 0 )