Line data Source code
1 : /****************************************************************************** 2 : * ETSI TS 103 634 V1.6.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 : static const LC3_FLOAT* mdct_window(LC3_INT length, LC3PLUS_FrameDuration frame_dms, LC3_INT hrmode) 15 : { 16 4398 : if (frame_dms == LC3PLUS_FRAME_DURATION_10MS) { 17 2380 : switch (length) { 18 0 : case 80: 19 0 : return MDCT_WINS_10ms[hrmode][0]; 20 4 : case 160: 21 4 : return MDCT_WINS_10ms[hrmode][1]; 22 0 : case 240: 23 0 : return MDCT_WINS_10ms[hrmode][2]; 24 4 : case 320: 25 4 : return MDCT_WINS_10ms[hrmode][3]; 26 2372 : case 480: 27 2372 : return MDCT_WINS_10ms[hrmode][4]; 28 0 : case 960: 29 0 : return MDCT_WINS_10ms[hrmode][5]; 30 0 : default: 31 0 : return NULL; 32 : } 33 : } 34 2018 : else if (frame_dms == LC3PLUS_FRAME_DURATION_7p5MS) { 35 0 : switch (length) { 36 0 : case 60: 37 0 : return MDCT_WINS_7_5ms[hrmode][0]; 38 0 : case 120: 39 0 : return MDCT_WINS_7_5ms[hrmode][1]; 40 0 : case 180: 41 0 : return MDCT_WINS_7_5ms[hrmode][2]; 42 0 : case 240: 43 0 : return MDCT_WINS_7_5ms[hrmode][3]; 44 0 : case 360: 45 0 : return MDCT_WINS_7_5ms[hrmode][4]; 46 0 : case 720: 47 0 : return MDCT_WINS_7_5ms[hrmode][5]; 48 0 : default: 49 0 : return NULL; 50 : } 51 : } 52 2018 : else if (frame_dms == LC3PLUS_FRAME_DURATION_5MS) { 53 2016 : switch (length) { 54 0 : case 40: 55 0 : return MDCT_WINS_5ms[hrmode][0]; 56 0 : case 80: 57 0 : return MDCT_WINS_5ms[hrmode][1]; 58 0 : case 120: 59 0 : return MDCT_WINS_5ms[hrmode][2]; 60 0 : case 160: 61 0 : return MDCT_WINS_5ms[hrmode][3]; 62 2016 : case 240: 63 2016 : return MDCT_WINS_5ms[hrmode][4]; 64 0 : case 480: 65 0 : return MDCT_WINS_5ms[hrmode][5]; 66 0 : default: 67 0 : return NULL; 68 : } 69 : } 70 2 : else if (frame_dms == LC3PLUS_FRAME_DURATION_2p5MS) { 71 2 : switch (length) { 72 0 : case 20: 73 0 : return MDCT_WINS_2_5ms[hrmode][0]; 74 0 : case 40: 75 0 : return MDCT_WINS_2_5ms[hrmode][1]; 76 0 : case 60: 77 0 : return MDCT_WINS_2_5ms[hrmode][2]; 78 0 : case 80: 79 0 : return MDCT_WINS_2_5ms[hrmode][3]; 80 2 : case 120: 81 2 : return MDCT_WINS_2_5ms[hrmode][4]; 82 0 : case 240: 83 0 : return MDCT_WINS_2_5ms[hrmode][5]; 84 0 : default: 85 0 : return NULL; 86 : } 87 : } 88 : #ifdef CR9_C_ADD_1p25MS 89 0 : else if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) { 90 0 : switch (length) { 91 0 : case 10: 92 0 : return MDCT_WINS_1_25ms[hrmode][0]; 93 0 : case 20: 94 0 : return MDCT_WINS_1_25ms[hrmode][1]; 95 0 : case 30: 96 0 : return MDCT_WINS_1_25ms[hrmode][2]; 97 0 : case 40: 98 0 : return MDCT_WINS_1_25ms[hrmode][3]; 99 0 : case 60: 100 0 : return MDCT_WINS_1_25ms[hrmode][4]; 101 0 : default: 102 0 : return NULL; 103 : } 104 : } 105 : #endif 106 0 : return NULL; 107 : } 108 : 109 4398 : void mdct_init(Mdct* mdct, LC3_INT length, LC3PLUS_FrameDuration frame_dms, LC3_INT fs_idx, LC3_INT hrmode) 110 : { 111 4398 : switch (frame_dms) 112 : { 113 : #ifdef CR9_C_ADD_1p25MS 114 0 : case LC3PLUS_FRAME_DURATION_1p25MS: 115 0 : mdct->leading_zeros = MDCT_la_zeroes_1_25ms[fs_idx]; 116 0 : break; 117 : #endif 118 2 : case LC3PLUS_FRAME_DURATION_2p5MS: 119 2 : mdct->leading_zeros = MDCT_la_zeroes_2_5ms[fs_idx]; 120 2 : break; 121 2016 : case LC3PLUS_FRAME_DURATION_5MS: 122 2016 : mdct->leading_zeros = MDCT_la_zeroes_5ms[fs_idx]; 123 2016 : break; 124 0 : case LC3PLUS_FRAME_DURATION_7p5MS: 125 0 : mdct->leading_zeros = MDCT_la_zeroes_7_5ms[fs_idx]; 126 0 : break; 127 2380 : case LC3PLUS_FRAME_DURATION_10MS: 128 2380 : mdct->leading_zeros = MDCT_la_zeroes[fs_idx]; 129 2380 : break; 130 0 : case LC3PLUS_FRAME_DURATION_UNDEFINED: 131 0 : assert(!"invalid frame_ms"); 132 : } 133 : 134 4398 : mdct->length = length; 135 4398 : mdct->mem_length = length - mdct->leading_zeros; 136 4398 : mdct->window = mdct_window(length, frame_dms, hrmode); 137 4398 : mdct->mem = calloc(mdct->mem_length, sizeof(*mdct->mem)); 138 4398 : dct4_init(&mdct->dct, length); 139 4398 : } 140 : 141 4398 : void mdct_free(Mdct* mdct) 142 : { 143 4398 : if (mdct) { 144 4398 : free(mdct->mem); 145 4398 : dct4_free(&mdct->dct); 146 4398 : memset(mdct, 0, sizeof(*mdct)); 147 : } 148 4398 : } 149 : 150 1189311 : void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct) 151 : { 152 : LC3_FLOAT tmp[MAX_LEN * 2]; 153 : LC3_INT i; 154 : LC3_INT hlen; 155 : 156 1189311 : move_float(tmp, mdct->mem, mdct->mem_length); 157 1189311 : move_float(tmp + mdct->mem_length, input, mdct->length); 158 1189311 : zero_float(tmp + mdct->length * 2 - mdct->leading_zeros, mdct->leading_zeros); 159 1189311 : move_float(mdct->mem, tmp + mdct->length, mdct->mem_length); 160 : 161 1189311 : mult_vec(tmp, mdct->window, mdct->length * 2); 162 : 163 1189311 : hlen = mdct->length / 2; 164 149901351 : for (i = 0; i < hlen; i++) { 165 148712040 : output[i] = -tmp[hlen * 3 - i - 1] - tmp[hlen * 3 + i]; 166 148712040 : output[hlen + i] = tmp[i] - tmp[hlen * 2 - i - 1]; 167 : } 168 : 169 1189311 : move_float(tmp, output, mdct->length); 170 : 171 1189311 : dct4_apply(&mdct->dct, tmp, output); 172 1189311 : } 173 : 174 1189311 : void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct) { mdct_apply(in, out, mdctStruct); }