Line data Source code
1 : /****************************************************************************** 2 : * ETSI TS 103 634 V1.5.1 * 3 : * Low Complexity Communication Codec Plus (LC3plus) * 4 : * * 5 : * Copyright licence is solely granted through ETSI Intellectual Property * 6 : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * 7 : * estoppel or otherwise. * 8 : ******************************************************************************/ 9 : 10 : #include "options.h" 11 : #include "wmc_auto.h" 12 : #include "functions.h" 13 : 14 1432 : void dct2_init(Dct2* dct, int length) 15 : { 16 1432 : assert(length <= MAX_LEN); 17 1432 : dct->length = length; 18 1432 : fft_init(&dct->fft, length); 19 1432 : } 20 : 21 1432 : void dct2_free(Dct2* dct) 22 : { 23 1432 : if (dct) { 24 1432 : fft_free(&dct->fft); 25 1432 : memset(dct, 0, sizeof(*dct)); 26 : } 27 1432 : } 28 : 29 590506 : void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output) 30 : { 31 : Complex tmp1[MAX_LEN]; 32 : Complex tmp2[MAX_LEN]; 33 : int i; 34 590506 : assert(input != output); 35 : 36 5314554 : for (i = 0; i < 8; i++) { 37 4724048 : tmp1[i] = cmplx(input[i * 2], 0); 38 4724048 : tmp1[16 - i - 1] = cmplx(input[i * 2 + 1], 0); 39 : } 40 : 41 590506 : fft_apply(&dct->fft, tmp1, tmp2); 42 : 43 10038602 : for (i = 0; i < 16; i++) { 44 9448096 : output[i] = cmul(tmp2[i], dct2_16[i]).r; 45 : } 46 590506 : output[0] /= (LC3_FLOAT)1.414213562373095; /* SQRT(2) */ 47 590506 : } 48 : 49 : 50 2864 : void dct4_init(Dct4* dct, int length) 51 : { 52 : int i; 53 2864 : assert(length <= MAX_LEN); 54 2864 : dct->length = length; 55 2864 : dct->twid1 = calloc(sizeof(*dct->twid1), length / 2); 56 2864 : dct->twid2 = calloc(sizeof(*dct->twid2), length / 2); 57 533744 : for (i = 0; i < length / 2; i++) { 58 530880 : dct->twid1[i] = cexpi(-(LC3_FLOAT)M_PI_LC3PLUS * (i + (LC3_FLOAT)0.25) / length); 59 530880 : dct->twid2[i] = cexpi(-(LC3_FLOAT)M_PI_LC3PLUS * i / length); 60 : } 61 2864 : fft_init(&dct->fft, length / 2); 62 2864 : } 63 : 64 2864 : void dct4_free(Dct4* dct) 65 : { 66 2864 : if (dct) { 67 2864 : free(dct->twid1); 68 2864 : free(dct->twid2); 69 2864 : fft_free(&dct->fft); 70 2864 : memset(dct, 0, sizeof(*dct)); 71 : } 72 2864 : } 73 : 74 1181012 : void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output) 75 : { 76 : Complex tmp2[MAX_LEN / 2]; 77 1181012 : int i = 0; 78 1181012 : Complex* tmp1 = (Complex*)output; 79 1181012 : const int len = dct->length; 80 1181012 : const LC3_FLOAT norm = (LC3_FLOAT)1.0 / LC3_SQRT((LC3_FLOAT)(len >> 1)); 81 1181012 : assert(input != output); 82 : 83 150628532 : for (i = 0; i < len >> 1; i++) { 84 149447520 : tmp1[i] = cmul(cmplx(input[i * 2], input[len - i * 2 - 1]), dct->twid1[i]); 85 : } 86 : 87 1181012 : fft_apply(&dct->fft, tmp1, tmp2); 88 : 89 150628532 : for (i = 0; i < len >> 1; i++) { 90 149447520 : Complex t = cmul(tmp2[i], dct->twid2[i]); 91 149447520 : output[i * 2] = t.r * norm; 92 149447520 : output[len - i * 2 - 1] = -t.i * norm; 93 : } 94 1181012 : }