1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "settings.h" 12 #include "fft.h" 13 #include "codec.h" 14 #include "os_specific_inline.h" 15 #include <math.h> 16 17 void WebRtcIsac_InitTransform(TransformTables* tables) { 18 int k; 19 double fact, phase; 20 21 fact = PI / (FRAMESAMPLES_HALF); 22 phase = 0.0; 23 for (k = 0; k < FRAMESAMPLES_HALF; k++) { 24 tables->costab1[k] = cos(phase); 25 tables->sintab1[k] = sin(phase); 26 phase += fact; 27 } 28 29 fact = PI * ((double) (FRAMESAMPLES_HALF - 1)) / ((double) FRAMESAMPLES_HALF); 30 phase = 0.5 * fact; 31 for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { 32 tables->costab2[k] = cos(phase); 33 tables->sintab2[k] = sin(phase); 34 phase += fact; 35 } 36 } 37 38 void WebRtcIsac_Time2Spec(const TransformTables* tables, 39 double* inre1, 40 double* inre2, 41 int16_t* outreQ7, 42 int16_t* outimQ7, 43 FFTstr* fftstr_obj) { 44 int k; 45 int dims[1]; 46 double tmp1r, tmp1i, xr, xi, yr, yi, fact; 47 double tmpre[FRAMESAMPLES_HALF], tmpim[FRAMESAMPLES_HALF]; 48 49 50 dims[0] = FRAMESAMPLES_HALF; 51 52 53 /* Multiply with complex exponentials and combine into one complex vector */ 54 fact = 0.5 / sqrt(FRAMESAMPLES_HALF); 55 for (k = 0; k < FRAMESAMPLES_HALF; k++) { 56 tmp1r = tables->costab1[k]; 57 tmp1i = tables->sintab1[k]; 58 tmpre[k] = (inre1[k] * tmp1r + inre2[k] * tmp1i) * fact; 59 tmpim[k] = (inre2[k] * tmp1r - inre1[k] * tmp1i) * fact; 60 } 61 62 63 /* Get DFT */ 64 WebRtcIsac_Fftns(1, dims, tmpre, tmpim, -1, 1.0, fftstr_obj); 65 66 /* Use symmetry to separate into two complex vectors and center frames in time around zero */ 67 for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { 68 xr = tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k]; 69 yi = -tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k]; 70 xi = tmpim[k] - tmpim[FRAMESAMPLES_HALF - 1 - k]; 71 yr = tmpim[k] + tmpim[FRAMESAMPLES_HALF - 1 - k]; 72 73 tmp1r = tables->costab2[k]; 74 tmp1i = tables->sintab2[k]; 75 outreQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1r - xi * tmp1i) * 128.0); 76 outimQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1i + xi * tmp1r) * 128.0); 77 outreQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)WebRtcIsac_lrint((-yr * tmp1i - yi * tmp1r) * 128.0); 78 outimQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)WebRtcIsac_lrint((-yr * tmp1r + yi * tmp1i) * 128.0); 79 } 80 } 81 82 void WebRtcIsac_Spec2time(const TransformTables* tables, 83 double* inre, 84 double* inim, 85 double* outre1, 86 double* outre2, 87 FFTstr* fftstr_obj) { 88 int k; 89 double tmp1r, tmp1i, xr, xi, yr, yi, fact; 90 91 int dims; 92 93 dims = FRAMESAMPLES_HALF; 94 95 for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { 96 /* Move zero in time to beginning of frames */ 97 tmp1r = tables->costab2[k]; 98 tmp1i = tables->sintab2[k]; 99 xr = inre[k] * tmp1r + inim[k] * tmp1i; 100 xi = inim[k] * tmp1r - inre[k] * tmp1i; 101 yr = -inim[FRAMESAMPLES_HALF - 1 - k] * tmp1r - inre[FRAMESAMPLES_HALF - 1 - k] * tmp1i; 102 yi = -inre[FRAMESAMPLES_HALF - 1 - k] * tmp1r + inim[FRAMESAMPLES_HALF - 1 - k] * tmp1i; 103 104 /* Combine into one vector, z = x + j * y */ 105 outre1[k] = xr - yi; 106 outre1[FRAMESAMPLES_HALF - 1 - k] = xr + yi; 107 outre2[k] = xi + yr; 108 outre2[FRAMESAMPLES_HALF - 1 - k] = -xi + yr; 109 } 110 111 112 /* Get IDFT */ 113 WebRtcIsac_Fftns(1, &dims, outre1, outre2, 1, FRAMESAMPLES_HALF, fftstr_obj); 114 115 116 /* Demodulate and separate */ 117 fact = sqrt(FRAMESAMPLES_HALF); 118 for (k = 0; k < FRAMESAMPLES_HALF; k++) { 119 tmp1r = tables->costab1[k]; 120 tmp1i = tables->sintab1[k]; 121 xr = (outre1[k] * tmp1r - outre2[k] * tmp1i) * fact; 122 outre2[k] = (outre2[k] * tmp1r + outre1[k] * tmp1i) * fact; 123 outre1[k] = xr; 124 } 125 } 126