Line data Source code
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 0 : void WebRtcIsac_InitTransform(TransformTables* tables) {
18 : int k;
19 : double fact, phase;
20 :
21 0 : fact = PI / (FRAMESAMPLES_HALF);
22 0 : phase = 0.0;
23 0 : for (k = 0; k < FRAMESAMPLES_HALF; k++) {
24 0 : tables->costab1[k] = cos(phase);
25 0 : tables->sintab1[k] = sin(phase);
26 0 : phase += fact;
27 : }
28 :
29 0 : fact = PI * ((double) (FRAMESAMPLES_HALF - 1)) / ((double) FRAMESAMPLES_HALF);
30 0 : phase = 0.5 * fact;
31 0 : for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
32 0 : tables->costab2[k] = cos(phase);
33 0 : tables->sintab2[k] = sin(phase);
34 0 : phase += fact;
35 : }
36 0 : }
37 :
38 0 : 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 0 : dims[0] = FRAMESAMPLES_HALF;
51 :
52 :
53 : /* Multiply with complex exponentials and combine into one complex vector */
54 0 : fact = 0.5 / sqrt(FRAMESAMPLES_HALF);
55 0 : for (k = 0; k < FRAMESAMPLES_HALF; k++) {
56 0 : tmp1r = tables->costab1[k];
57 0 : tmp1i = tables->sintab1[k];
58 0 : tmpre[k] = (inre1[k] * tmp1r + inre2[k] * tmp1i) * fact;
59 0 : tmpim[k] = (inre2[k] * tmp1r - inre1[k] * tmp1i) * fact;
60 : }
61 :
62 :
63 : /* Get DFT */
64 0 : 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 0 : for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
68 0 : xr = tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k];
69 0 : yi = -tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k];
70 0 : xi = tmpim[k] - tmpim[FRAMESAMPLES_HALF - 1 - k];
71 0 : yr = tmpim[k] + tmpim[FRAMESAMPLES_HALF - 1 - k];
72 :
73 0 : tmp1r = tables->costab2[k];
74 0 : tmp1i = tables->sintab2[k];
75 0 : outreQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1r - xi * tmp1i) * 128.0);
76 0 : outimQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1i + xi * tmp1r) * 128.0);
77 0 : outreQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)WebRtcIsac_lrint((-yr * tmp1i - yi * tmp1r) * 128.0);
78 0 : outimQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)WebRtcIsac_lrint((-yr * tmp1r + yi * tmp1i) * 128.0);
79 : }
80 0 : }
81 :
82 0 : 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 0 : dims = FRAMESAMPLES_HALF;
94 :
95 0 : for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
96 : /* Move zero in time to beginning of frames */
97 0 : tmp1r = tables->costab2[k];
98 0 : tmp1i = tables->sintab2[k];
99 0 : xr = inre[k] * tmp1r + inim[k] * tmp1i;
100 0 : xi = inim[k] * tmp1r - inre[k] * tmp1i;
101 0 : yr = -inim[FRAMESAMPLES_HALF - 1 - k] * tmp1r - inre[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
102 0 : yi = -inre[FRAMESAMPLES_HALF - 1 - k] * tmp1r + inim[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
103 :
104 : /* Combine into one vector, z = x + j * y */
105 0 : outre1[k] = xr - yi;
106 0 : outre1[FRAMESAMPLES_HALF - 1 - k] = xr + yi;
107 0 : outre2[k] = xi + yr;
108 0 : outre2[FRAMESAMPLES_HALF - 1 - k] = -xi + yr;
109 : }
110 :
111 :
112 : /* Get IDFT */
113 0 : WebRtcIsac_Fftns(1, &dims, outre1, outre2, 1, FRAMESAMPLES_HALF, fftstr_obj);
114 :
115 :
116 : /* Demodulate and separate */
117 0 : fact = sqrt(FRAMESAMPLES_HALF);
118 0 : for (k = 0; k < FRAMESAMPLES_HALF; k++) {
119 0 : tmp1r = tables->costab1[k];
120 0 : tmp1i = tables->sintab1[k];
121 0 : xr = (outre1[k] * tmp1r - outre2[k] * tmp1i) * fact;
122 0 : outre2[k] = (outre2[k] * tmp1r + outre1[k] * tmp1i) * fact;
123 0 : outre1[k] = xr;
124 : }
125 0 : }
|