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