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 : static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT hrmode) 15 : { 16 0 : if (frame_dms == 100) { 17 0 : switch (length) { 18 0 : case 80: 19 0 : return MDCT_WINS_10ms[hrmode][0]; 20 0 : case 160: 21 0 : return MDCT_WINS_10ms[hrmode][1]; 22 0 : case 240: 23 0 : return MDCT_WINS_10ms[hrmode][2]; 24 0 : case 320: 25 0 : return MDCT_WINS_10ms[hrmode][3]; 26 0 : case 480: 27 0 : 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 0 : else if (frame_dms == 75) { 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 0 : else if (frame_dms == 50) { 53 0 : 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 0 : case 240: 63 0 : 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 0 : else if (frame_dms == 25) { 71 0 : 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 0 : case 120: 81 0 : 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 0 : return NULL; 89 : } 90 : 91 0 : void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC3_INT hrmode) 92 : { 93 0 : if (frame_dms == 100) { 94 0 : mdct->leading_zeros = MDCT_la_zeroes[fs_idx]; 95 : } 96 0 : else if (frame_dms == 75) { 97 0 : mdct->leading_zeros = MDCT_la_zeroes_7_5ms[fs_idx]; 98 : } 99 0 : else if (frame_dms == 50) { 100 0 : mdct->leading_zeros = MDCT_la_zeroes_5ms[fs_idx]; 101 : } 102 0 : else if (frame_dms == 25) { 103 0 : mdct->leading_zeros = MDCT_la_zeroes_2_5ms[fs_idx]; 104 : } 105 : else { 106 0 : assert(!"invalid frame_ms"); 107 : } 108 : 109 0 : mdct->length = length; 110 0 : mdct->mem_length = length - mdct->leading_zeros; 111 0 : mdct->window = mdct_window(length, frame_dms, hrmode); 112 0 : mdct->mem = calloc(sizeof(*mdct->mem), mdct->mem_length); 113 0 : dct4_init(&mdct->dct, length); 114 0 : } 115 : 116 0 : void mdct_free(Mdct* mdct) 117 : { 118 0 : if (mdct) { 119 0 : free(mdct->mem); 120 0 : dct4_free(&mdct->dct); 121 0 : memset(mdct, 0, sizeof(*mdct)); 122 : } 123 0 : } 124 : 125 0 : void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct) 126 : { 127 : LC3_FLOAT tmp[MAX_LEN * 2]; 128 : LC3_INT i; 129 : LC3_INT hlen; 130 : 131 0 : move_float(tmp, mdct->mem, mdct->mem_length); 132 0 : move_float(tmp + mdct->mem_length, input, mdct->length); 133 0 : zero_float(tmp + mdct->length * 2 - mdct->leading_zeros, mdct->leading_zeros); 134 0 : move_float(mdct->mem, tmp + mdct->length, mdct->mem_length); 135 : 136 0 : mult_vec(tmp, mdct->window, mdct->length * 2); 137 : 138 0 : hlen = mdct->length / 2; 139 0 : for (i = 0; i < hlen; i++) { 140 0 : output[i] = -tmp[hlen * 3 - i - 1] - tmp[hlen * 3 + i]; 141 0 : output[hlen + i] = tmp[i] - tmp[hlen * 2 - i - 1]; 142 : } 143 : 144 0 : move_float(tmp, output, mdct->length); 145 : 146 0 : dct4_apply(&mdct->dct, tmp, output); 147 0 : } 148 : 149 0 : void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct) { mdct_apply(in, out, mdctStruct); }