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
WebRtcIsac_InitTransform(TransformTables * tables)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
WebRtcIsac_Time2Spec(const TransformTables * tables,double * inre1,double * inre2,int16_t * outreQ7,int16_t * outimQ7,FFTstr * fftstr_obj)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
WebRtcIsac_Spec2time(const TransformTables * tables,double * inre,double * inim,double * outre1,double * outre2,FFTstr * fftstr_obj)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