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 4398 : void dct2_init(Dct2* dct, int length) 15 : { 16 4398 : assert(length <= MAX_LEN); 17 4398 : dct->length = length; 18 4398 : fft_init(&dct->fft, length); 19 4398 : } 20 : 21 4398 : void dct2_free(Dct2* dct) 22 : { 23 4398 : if (dct) { 24 4398 : fft_free(&dct->fft); 25 4398 : memset(dct, 0, sizeof(*dct)); 26 : } 27 4398 : } 28 : 29 1189311 : 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 1189311 : assert(input != output); 35 : 36 10703799 : for (i = 0; i < 8; i++) { 37 9514488 : tmp1[i] = cmplx(input[i * 2], 0); 38 9514488 : tmp1[16 - i - 1] = cmplx(input[i * 2 + 1], 0); 39 : } 40 : 41 1189311 : fft_apply(&dct->fft, tmp1, tmp2); 42 : 43 20218287 : for (i = 0; i < 16; i++) { 44 19028976 : output[i] = cmul(tmp2[i], dct2_16[i]).r; 45 : } 46 1189311 : output[0] /= (LC3_FLOAT)1.414213562373095; /* SQRT(2) */ 47 1189311 : } 48 : 49 : 50 8793 : void dct4_init(Dct4* dct, int length) 51 : { 52 : int i; 53 8793 : assert(length <= MAX_LEN); 54 8793 : dct->length = length; 55 8793 : dct->twid1 = calloc(sizeof(*dct->twid1), length / 2); 56 8793 : dct->twid2 = calloc(sizeof(*dct->twid2), length / 2); 57 1632873 : for (i = 0; i < length / 2; i++) { 58 1624080 : dct->twid1[i] = cexpi(-(LC3_FLOAT)M_PI_LC3PLUS * (i + (LC3_FLOAT)0.25) / length); 59 1624080 : dct->twid2[i] = cexpi(-(LC3_FLOAT)M_PI_LC3PLUS * i / length); 60 : } 61 8793 : fft_init(&dct->fft, length / 2); 62 8793 : } 63 : 64 8793 : void dct4_free(Dct4* dct) 65 : { 66 8793 : if (dct) { 67 8793 : free(dct->twid1); 68 8793 : free(dct->twid2); 69 8793 : fft_free(&dct->fft); 70 8793 : memset(dct, 0, sizeof(*dct)); 71 : } 72 8793 : } 73 : 74 2368928 : void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output) 75 : { 76 : Complex tmp2[MAX_LEN / 2]; 77 2368928 : int i = 0; 78 2368928 : Complex* tmp1 = (Complex*)output; 79 2368928 : const int len = dct->length; 80 2368928 : const LC3_FLOAT norm = (LC3_FLOAT)1.0 / LC3_SQRT((LC3_FLOAT)(len >> 1)); 81 2368928 : assert(input != output); 82 : 83 298625888 : for (i = 0; i < len >> 1; i++) { 84 296256960 : tmp1[i] = cmul(cmplx(input[i * 2], input[len - i * 2 - 1]), dct->twid1[i]); 85 : } 86 : 87 2368928 : fft_apply(&dct->fft, tmp1, tmp2); 88 : 89 298625888 : for (i = 0; i < len >> 1; i++) { 90 296256960 : Complex t = cmul(tmp2[i], dct->twid2[i]); 91 296256960 : output[i * 2] = t.r * norm; 92 296256960 : output[len - i * 2 - 1] = -t.i * norm; 93 : } 94 2368928 : }