/proc/self/cwd/libfaad/sbr_hfgen.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding |
3 | | ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com |
4 | | ** |
5 | | ** This program is free software; you can redistribute it and/or modify |
6 | | ** it under the terms of the GNU General Public License as published by |
7 | | ** the Free Software Foundation; either version 2 of the License, or |
8 | | ** (at your option) any later version. |
9 | | ** |
10 | | ** This program is distributed in the hope that it will be useful, |
11 | | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | ** GNU General Public License for more details. |
14 | | ** |
15 | | ** You should have received a copy of the GNU General Public License |
16 | | ** along with this program; if not, write to the Free Software |
17 | | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 | | ** |
19 | | ** Any non-GPL usage of this software or parts of this software is strictly |
20 | | ** forbidden. |
21 | | ** |
22 | | ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 |
23 | | ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" |
24 | | ** |
25 | | ** Commercial non-GPL licensing of this software is possible. |
26 | | ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. |
27 | | ** |
28 | | ** $Id: sbr_hfgen.c,v 1.26 2007/11/01 12:33:35 menno Exp $ |
29 | | **/ |
30 | | |
31 | | /* High Frequency generation */ |
32 | | |
33 | | #include "common.h" |
34 | | #include "structs.h" |
35 | | |
36 | | #ifdef SBR_DEC |
37 | | |
38 | | #include "sbr_syntax.h" |
39 | | #include "sbr_hfgen.h" |
40 | | #include "sbr_fbt.h" |
41 | | |
42 | | /* static function declarations */ |
43 | | #ifdef SBR_LOW_POWER |
44 | | static void calc_prediction_coef_lp(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], |
45 | | complex_t *alpha_0, complex_t *alpha_1, real_t *rxx); |
46 | | static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg); |
47 | | #else |
48 | | static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], |
49 | | complex_t *alpha_0, complex_t *alpha_1, uint8_t k); |
50 | | #endif |
51 | | static void calc_chirp_factors(sbr_info *sbr, uint8_t ch); |
52 | | static void patch_construction(sbr_info *sbr); |
53 | | |
54 | | |
55 | | void hf_generation(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], |
56 | | qmf_t Xhigh[MAX_NTSRHFG][64] |
57 | | #ifdef SBR_LOW_POWER |
58 | | ,real_t *deg |
59 | | #endif |
60 | | ,uint8_t ch) |
61 | 48.6k | { |
62 | 48.6k | uint8_t l, i, x; |
63 | 48.6k | ALIGN complex_t alpha_0[64], alpha_1[64]; |
64 | | #ifdef SBR_LOW_POWER |
65 | | ALIGN real_t rxx[64]; |
66 | | #endif |
67 | | |
68 | 48.6k | uint8_t offset = sbr->tHFAdj; |
69 | 48.6k | uint8_t first = sbr->t_E[ch][0]; |
70 | 48.6k | uint8_t last = sbr->t_E[ch][sbr->L_E[ch]]; |
71 | | |
72 | 48.6k | calc_chirp_factors(sbr, ch); |
73 | | |
74 | | #ifdef SBR_LOW_POWER |
75 | | memset(deg, 0, 64*sizeof(real_t)); |
76 | | #endif |
77 | | |
78 | 48.6k | if ((ch == 0) && (sbr->Reset)) |
79 | 37.7k | patch_construction(sbr); |
80 | | |
81 | | /* calculate the prediction coefficients */ |
82 | | #ifdef SBR_LOW_POWER |
83 | | calc_prediction_coef_lp(sbr, Xlow, alpha_0, alpha_1, rxx); |
84 | | calc_aliasing_degree(sbr, rxx, deg); |
85 | | #endif |
86 | | |
87 | | /* actual HF generation */ |
88 | 148k | for (i = 0; i < sbr->noPatches; i++) |
89 | 99.8k | { |
90 | 729k | for (x = 0; x < sbr->patchNoSubbands[i]; x++) |
91 | 629k | { |
92 | 629k | real_t a0_r, a0_i, a1_r, a1_i; |
93 | 629k | real_t bw, bw2; |
94 | 629k | uint8_t q, p, k, g; |
95 | | |
96 | | /* find the low and high band for patching */ |
97 | 629k | k = sbr->kx + x; |
98 | 1.17M | for (q = 0; q < i; q++) |
99 | 543k | { |
100 | 543k | k += sbr->patchNoSubbands[q]; |
101 | 543k | } |
102 | 629k | p = sbr->patchStartSubband[i] + x; |
103 | | |
104 | | #ifdef SBR_LOW_POWER |
105 | | if (x != 0 /*x < sbr->patchNoSubbands[i]-1*/) |
106 | | deg[k] = deg[p]; |
107 | | else |
108 | | deg[k] = 0; |
109 | | #endif |
110 | | |
111 | 629k | g = sbr->table_map_k_to_g[k]; |
112 | | |
113 | 629k | bw = sbr->bwArray[ch][g]; |
114 | 629k | bw2 = MUL_C(bw, bw); |
115 | | |
116 | | /* do the patching */ |
117 | | /* with or without filtering */ |
118 | 629k | if (bw2 > 0) |
119 | 321k | { |
120 | 321k | real_t temp1_r, temp2_r, temp3_r; |
121 | 321k | #ifndef SBR_LOW_POWER |
122 | 321k | real_t temp1_i, temp2_i, temp3_i; |
123 | 321k | calc_prediction_coef(sbr, Xlow, alpha_0, alpha_1, p); |
124 | 321k | #endif |
125 | | |
126 | 321k | a0_r = MUL_C(RE(alpha_0[p]), bw); |
127 | 321k | a1_r = MUL_C(RE(alpha_1[p]), bw2); |
128 | 321k | #ifndef SBR_LOW_POWER |
129 | 321k | a0_i = MUL_C(IM(alpha_0[p]), bw); |
130 | 321k | a1_i = MUL_C(IM(alpha_1[p]), bw2); |
131 | 321k | #endif |
132 | | |
133 | 321k | temp2_r = QMF_RE(Xlow[first - 2 + offset][p]); |
134 | 321k | temp3_r = QMF_RE(Xlow[first - 1 + offset][p]); |
135 | 321k | #ifndef SBR_LOW_POWER |
136 | 321k | temp2_i = QMF_IM(Xlow[first - 2 + offset][p]); |
137 | 321k | temp3_i = QMF_IM(Xlow[first - 1 + offset][p]); |
138 | 321k | #endif |
139 | 10.5M | for (l = first; l < last; l++) |
140 | 10.2M | { |
141 | 10.2M | temp1_r = temp2_r; |
142 | 10.2M | temp2_r = temp3_r; |
143 | 10.2M | temp3_r = QMF_RE(Xlow[l + offset][p]); |
144 | 10.2M | #ifndef SBR_LOW_POWER |
145 | 10.2M | temp1_i = temp2_i; |
146 | 10.2M | temp2_i = temp3_i; |
147 | 10.2M | temp3_i = QMF_IM(Xlow[l + offset][p]); |
148 | 10.2M | #endif |
149 | | |
150 | | #ifdef SBR_LOW_POWER |
151 | | QMF_RE(Xhigh[l + offset][k]) = |
152 | | temp3_r |
153 | | +(MUL_R(a0_r, temp2_r) + |
154 | | MUL_R(a1_r, temp1_r)); |
155 | | #else |
156 | 10.2M | QMF_RE(Xhigh[l + offset][k]) = |
157 | 10.2M | temp3_r |
158 | 10.2M | +(MUL_R(a0_r, temp2_r) - |
159 | 10.2M | MUL_R(a0_i, temp2_i) + |
160 | 10.2M | MUL_R(a1_r, temp1_r) - |
161 | 10.2M | MUL_R(a1_i, temp1_i)); |
162 | 10.2M | QMF_IM(Xhigh[l + offset][k]) = |
163 | 10.2M | temp3_i |
164 | 10.2M | +(MUL_R(a0_i, temp2_r) + |
165 | 10.2M | MUL_R(a0_r, temp2_i) + |
166 | 10.2M | MUL_R(a1_i, temp1_r) + |
167 | 10.2M | MUL_R(a1_r, temp1_i)); |
168 | 10.2M | #endif |
169 | 10.2M | } |
170 | 321k | } else { |
171 | 10.0M | for (l = first; l < last; l++) |
172 | 9.73M | { |
173 | 9.73M | QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]); |
174 | 9.73M | #ifndef SBR_LOW_POWER |
175 | 9.73M | QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]); |
176 | 9.73M | #endif |
177 | 9.73M | } |
178 | 307k | } |
179 | 629k | } |
180 | 99.8k | } |
181 | | |
182 | 48.6k | if (sbr->Reset) |
183 | 46.9k | { |
184 | 46.9k | limiter_frequency_table(sbr); |
185 | 46.9k | } |
186 | 48.6k | } Line | Count | Source | 61 | 24.3k | { | 62 | 24.3k | uint8_t l, i, x; | 63 | 24.3k | ALIGN complex_t alpha_0[64], alpha_1[64]; | 64 | | #ifdef SBR_LOW_POWER | 65 | | ALIGN real_t rxx[64]; | 66 | | #endif | 67 | | | 68 | 24.3k | uint8_t offset = sbr->tHFAdj; | 69 | 24.3k | uint8_t first = sbr->t_E[ch][0]; | 70 | 24.3k | uint8_t last = sbr->t_E[ch][sbr->L_E[ch]]; | 71 | | | 72 | 24.3k | calc_chirp_factors(sbr, ch); | 73 | | | 74 | | #ifdef SBR_LOW_POWER | 75 | | memset(deg, 0, 64*sizeof(real_t)); | 76 | | #endif | 77 | | | 78 | 24.3k | if ((ch == 0) && (sbr->Reset)) | 79 | 18.8k | patch_construction(sbr); | 80 | | | 81 | | /* calculate the prediction coefficients */ | 82 | | #ifdef SBR_LOW_POWER | 83 | | calc_prediction_coef_lp(sbr, Xlow, alpha_0, alpha_1, rxx); | 84 | | calc_aliasing_degree(sbr, rxx, deg); | 85 | | #endif | 86 | | | 87 | | /* actual HF generation */ | 88 | 74.2k | for (i = 0; i < sbr->noPatches; i++) | 89 | 49.9k | { | 90 | 364k | for (x = 0; x < sbr->patchNoSubbands[i]; x++) | 91 | 314k | { | 92 | 314k | real_t a0_r, a0_i, a1_r, a1_i; | 93 | 314k | real_t bw, bw2; | 94 | 314k | uint8_t q, p, k, g; | 95 | | | 96 | | /* find the low and high band for patching */ | 97 | 314k | k = sbr->kx + x; | 98 | 586k | for (q = 0; q < i; q++) | 99 | 271k | { | 100 | 271k | k += sbr->patchNoSubbands[q]; | 101 | 271k | } | 102 | 314k | p = sbr->patchStartSubband[i] + x; | 103 | | | 104 | | #ifdef SBR_LOW_POWER | 105 | | if (x != 0 /*x < sbr->patchNoSubbands[i]-1*/) | 106 | | deg[k] = deg[p]; | 107 | | else | 108 | | deg[k] = 0; | 109 | | #endif | 110 | | | 111 | 314k | g = sbr->table_map_k_to_g[k]; | 112 | | | 113 | 314k | bw = sbr->bwArray[ch][g]; | 114 | 314k | bw2 = MUL_C(bw, bw); | 115 | | | 116 | | /* do the patching */ | 117 | | /* with or without filtering */ | 118 | 314k | if (bw2 > 0) | 119 | 160k | { | 120 | 160k | real_t temp1_r, temp2_r, temp3_r; | 121 | 160k | #ifndef SBR_LOW_POWER | 122 | 160k | real_t temp1_i, temp2_i, temp3_i; | 123 | 160k | calc_prediction_coef(sbr, Xlow, alpha_0, alpha_1, p); | 124 | 160k | #endif | 125 | | | 126 | 160k | a0_r = MUL_C(RE(alpha_0[p]), bw); | 127 | 160k | a1_r = MUL_C(RE(alpha_1[p]), bw2); | 128 | 160k | #ifndef SBR_LOW_POWER | 129 | 160k | a0_i = MUL_C(IM(alpha_0[p]), bw); | 130 | 160k | a1_i = MUL_C(IM(alpha_1[p]), bw2); | 131 | 160k | #endif | 132 | | | 133 | 160k | temp2_r = QMF_RE(Xlow[first - 2 + offset][p]); | 134 | 160k | temp3_r = QMF_RE(Xlow[first - 1 + offset][p]); | 135 | 160k | #ifndef SBR_LOW_POWER | 136 | 160k | temp2_i = QMF_IM(Xlow[first - 2 + offset][p]); | 137 | 160k | temp3_i = QMF_IM(Xlow[first - 1 + offset][p]); | 138 | 160k | #endif | 139 | 5.27M | for (l = first; l < last; l++) | 140 | 5.11M | { | 141 | 5.11M | temp1_r = temp2_r; | 142 | 5.11M | temp2_r = temp3_r; | 143 | 5.11M | temp3_r = QMF_RE(Xlow[l + offset][p]); | 144 | 5.11M | #ifndef SBR_LOW_POWER | 145 | 5.11M | temp1_i = temp2_i; | 146 | 5.11M | temp2_i = temp3_i; | 147 | 5.11M | temp3_i = QMF_IM(Xlow[l + offset][p]); | 148 | 5.11M | #endif | 149 | | | 150 | | #ifdef SBR_LOW_POWER | 151 | | QMF_RE(Xhigh[l + offset][k]) = | 152 | | temp3_r | 153 | | +(MUL_R(a0_r, temp2_r) + | 154 | | MUL_R(a1_r, temp1_r)); | 155 | | #else | 156 | 5.11M | QMF_RE(Xhigh[l + offset][k]) = | 157 | 5.11M | temp3_r | 158 | 5.11M | +(MUL_R(a0_r, temp2_r) - | 159 | 5.11M | MUL_R(a0_i, temp2_i) + | 160 | 5.11M | MUL_R(a1_r, temp1_r) - | 161 | 5.11M | MUL_R(a1_i, temp1_i)); | 162 | 5.11M | QMF_IM(Xhigh[l + offset][k]) = | 163 | 5.11M | temp3_i | 164 | 5.11M | +(MUL_R(a0_i, temp2_r) + | 165 | 5.11M | MUL_R(a0_r, temp2_i) + | 166 | 5.11M | MUL_R(a1_i, temp1_r) + | 167 | 5.11M | MUL_R(a1_r, temp1_i)); | 168 | 5.11M | #endif | 169 | 5.11M | } | 170 | 160k | } else { | 171 | 5.02M | for (l = first; l < last; l++) | 172 | 4.86M | { | 173 | 4.86M | QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]); | 174 | 4.86M | #ifndef SBR_LOW_POWER | 175 | 4.86M | QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]); | 176 | 4.86M | #endif | 177 | 4.86M | } | 178 | 153k | } | 179 | 314k | } | 180 | 49.9k | } | 181 | | | 182 | 24.3k | if (sbr->Reset) | 183 | 23.4k | { | 184 | 23.4k | limiter_frequency_table(sbr); | 185 | 23.4k | } | 186 | 24.3k | } |
Line | Count | Source | 61 | 24.3k | { | 62 | 24.3k | uint8_t l, i, x; | 63 | 24.3k | ALIGN complex_t alpha_0[64], alpha_1[64]; | 64 | | #ifdef SBR_LOW_POWER | 65 | | ALIGN real_t rxx[64]; | 66 | | #endif | 67 | | | 68 | 24.3k | uint8_t offset = sbr->tHFAdj; | 69 | 24.3k | uint8_t first = sbr->t_E[ch][0]; | 70 | 24.3k | uint8_t last = sbr->t_E[ch][sbr->L_E[ch]]; | 71 | | | 72 | 24.3k | calc_chirp_factors(sbr, ch); | 73 | | | 74 | | #ifdef SBR_LOW_POWER | 75 | | memset(deg, 0, 64*sizeof(real_t)); | 76 | | #endif | 77 | | | 78 | 24.3k | if ((ch == 0) && (sbr->Reset)) | 79 | 18.8k | patch_construction(sbr); | 80 | | | 81 | | /* calculate the prediction coefficients */ | 82 | | #ifdef SBR_LOW_POWER | 83 | | calc_prediction_coef_lp(sbr, Xlow, alpha_0, alpha_1, rxx); | 84 | | calc_aliasing_degree(sbr, rxx, deg); | 85 | | #endif | 86 | | | 87 | | /* actual HF generation */ | 88 | 74.2k | for (i = 0; i < sbr->noPatches; i++) | 89 | 49.9k | { | 90 | 364k | for (x = 0; x < sbr->patchNoSubbands[i]; x++) | 91 | 314k | { | 92 | 314k | real_t a0_r, a0_i, a1_r, a1_i; | 93 | 314k | real_t bw, bw2; | 94 | 314k | uint8_t q, p, k, g; | 95 | | | 96 | | /* find the low and high band for patching */ | 97 | 314k | k = sbr->kx + x; | 98 | 586k | for (q = 0; q < i; q++) | 99 | 271k | { | 100 | 271k | k += sbr->patchNoSubbands[q]; | 101 | 271k | } | 102 | 314k | p = sbr->patchStartSubband[i] + x; | 103 | | | 104 | | #ifdef SBR_LOW_POWER | 105 | | if (x != 0 /*x < sbr->patchNoSubbands[i]-1*/) | 106 | | deg[k] = deg[p]; | 107 | | else | 108 | | deg[k] = 0; | 109 | | #endif | 110 | | | 111 | 314k | g = sbr->table_map_k_to_g[k]; | 112 | | | 113 | 314k | bw = sbr->bwArray[ch][g]; | 114 | 314k | bw2 = MUL_C(bw, bw); | 115 | | | 116 | | /* do the patching */ | 117 | | /* with or without filtering */ | 118 | 314k | if (bw2 > 0) | 119 | 160k | { | 120 | 160k | real_t temp1_r, temp2_r, temp3_r; | 121 | 160k | #ifndef SBR_LOW_POWER | 122 | 160k | real_t temp1_i, temp2_i, temp3_i; | 123 | 160k | calc_prediction_coef(sbr, Xlow, alpha_0, alpha_1, p); | 124 | 160k | #endif | 125 | | | 126 | 160k | a0_r = MUL_C(RE(alpha_0[p]), bw); | 127 | 160k | a1_r = MUL_C(RE(alpha_1[p]), bw2); | 128 | 160k | #ifndef SBR_LOW_POWER | 129 | 160k | a0_i = MUL_C(IM(alpha_0[p]), bw); | 130 | 160k | a1_i = MUL_C(IM(alpha_1[p]), bw2); | 131 | 160k | #endif | 132 | | | 133 | 160k | temp2_r = QMF_RE(Xlow[first - 2 + offset][p]); | 134 | 160k | temp3_r = QMF_RE(Xlow[first - 1 + offset][p]); | 135 | 160k | #ifndef SBR_LOW_POWER | 136 | 160k | temp2_i = QMF_IM(Xlow[first - 2 + offset][p]); | 137 | 160k | temp3_i = QMF_IM(Xlow[first - 1 + offset][p]); | 138 | 160k | #endif | 139 | 5.27M | for (l = first; l < last; l++) | 140 | 5.11M | { | 141 | 5.11M | temp1_r = temp2_r; | 142 | 5.11M | temp2_r = temp3_r; | 143 | 5.11M | temp3_r = QMF_RE(Xlow[l + offset][p]); | 144 | 5.11M | #ifndef SBR_LOW_POWER | 145 | 5.11M | temp1_i = temp2_i; | 146 | 5.11M | temp2_i = temp3_i; | 147 | 5.11M | temp3_i = QMF_IM(Xlow[l + offset][p]); | 148 | 5.11M | #endif | 149 | | | 150 | | #ifdef SBR_LOW_POWER | 151 | | QMF_RE(Xhigh[l + offset][k]) = | 152 | | temp3_r | 153 | | +(MUL_R(a0_r, temp2_r) + | 154 | | MUL_R(a1_r, temp1_r)); | 155 | | #else | 156 | 5.11M | QMF_RE(Xhigh[l + offset][k]) = | 157 | 5.11M | temp3_r | 158 | 5.11M | +(MUL_R(a0_r, temp2_r) - | 159 | 5.11M | MUL_R(a0_i, temp2_i) + | 160 | 5.11M | MUL_R(a1_r, temp1_r) - | 161 | 5.11M | MUL_R(a1_i, temp1_i)); | 162 | 5.11M | QMF_IM(Xhigh[l + offset][k]) = | 163 | 5.11M | temp3_i | 164 | 5.11M | +(MUL_R(a0_i, temp2_r) + | 165 | 5.11M | MUL_R(a0_r, temp2_i) + | 166 | 5.11M | MUL_R(a1_i, temp1_r) + | 167 | 5.11M | MUL_R(a1_r, temp1_i)); | 168 | 5.11M | #endif | 169 | 5.11M | } | 170 | 160k | } else { | 171 | 5.02M | for (l = first; l < last; l++) | 172 | 4.86M | { | 173 | 4.86M | QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]); | 174 | 4.86M | #ifndef SBR_LOW_POWER | 175 | 4.86M | QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]); | 176 | 4.86M | #endif | 177 | 4.86M | } | 178 | 153k | } | 179 | 314k | } | 180 | 49.9k | } | 181 | | | 182 | 24.3k | if (sbr->Reset) | 183 | 23.4k | { | 184 | 23.4k | limiter_frequency_table(sbr); | 185 | 23.4k | } | 186 | 24.3k | } |
|
187 | | |
188 | | typedef struct |
189 | | { |
190 | | complex_t r01; |
191 | | complex_t r02; |
192 | | complex_t r11; |
193 | | complex_t r12; |
194 | | complex_t r22; |
195 | | real_t det; |
196 | | } acorr_coef; |
197 | | |
198 | | #ifdef SBR_LOW_POWER |
199 | | static void auto_correlation(sbr_info *sbr, acorr_coef *ac, |
200 | | qmf_t buffer[MAX_NTSRHFG][64], |
201 | | uint8_t bd, uint8_t len) |
202 | | { |
203 | | real_t r01 = 0, r02 = 0, r11 = 0; |
204 | | int8_t j; |
205 | | uint8_t offset = sbr->tHFAdj; |
206 | | #ifdef FIXED_POINT |
207 | | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); |
208 | | uint32_t maxi = 0; |
209 | | uint32_t pow2, exp; |
210 | | #else |
211 | | const real_t rel = 1 / (1 + 1e-6f); |
212 | | #endif |
213 | | |
214 | | |
215 | | #ifdef FIXED_POINT |
216 | | mask = 0; |
217 | | |
218 | | for (j = (offset-2); j < (len + offset); j++) |
219 | | { |
220 | | real_t x; |
221 | | x = QMF_RE(buffer[j][bd])>>REAL_BITS; |
222 | | mask |= x ^ (x >> 31); |
223 | | } |
224 | | |
225 | | exp = wl_min_lzc(mask); |
226 | | |
227 | | /* improves accuracy */ |
228 | | if (exp > 0) |
229 | | exp -= 1; |
230 | | |
231 | | for (j = offset; j < len + offset; j++) |
232 | | { |
233 | | real_t buf_j = ((QMF_RE(buffer[j][bd])+(1<<(exp-1)))>>exp); |
234 | | real_t buf_j_1 = ((QMF_RE(buffer[j-1][bd])+(1<<(exp-1)))>>exp); |
235 | | real_t buf_j_2 = ((QMF_RE(buffer[j-2][bd])+(1<<(exp-1)))>>exp); |
236 | | |
237 | | /* normalisation with rounding */ |
238 | | r01 += MUL_R(buf_j, buf_j_1); |
239 | | r02 += MUL_R(buf_j, buf_j_2); |
240 | | r11 += MUL_R(buf_j_1, buf_j_1); |
241 | | } |
242 | | RE(ac->r12) = r01 - |
243 | | MUL_R(((QMF_RE(buffer[len+offset-1][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[len+offset-2][bd])+(1<<(exp-1)))>>exp)) + |
244 | | MUL_R(((QMF_RE(buffer[offset-1][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[offset-2][bd])+(1<<(exp-1)))>>exp)); |
245 | | RE(ac->r22) = r11 - |
246 | | MUL_R(((QMF_RE(buffer[len+offset-2][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[len+offset-2][bd])+(1<<(exp-1)))>>exp)) + |
247 | | MUL_R(((QMF_RE(buffer[offset-2][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[offset-2][bd])+(1<<(exp-1)))>>exp)); |
248 | | #else |
249 | | for (j = offset; j < len + offset; j++) |
250 | | { |
251 | | r01 += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-1][bd]); |
252 | | r02 += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-2][bd]); |
253 | | r11 += QMF_RE(buffer[j-1][bd]) * QMF_RE(buffer[j-1][bd]); |
254 | | } |
255 | | RE(ac->r12) = r01 - |
256 | | QMF_RE(buffer[len+offset-1][bd]) * QMF_RE(buffer[len+offset-2][bd]) + |
257 | | QMF_RE(buffer[offset-1][bd]) * QMF_RE(buffer[offset-2][bd]); |
258 | | RE(ac->r22) = r11 - |
259 | | QMF_RE(buffer[len+offset-2][bd]) * QMF_RE(buffer[len+offset-2][bd]) + |
260 | | QMF_RE(buffer[offset-2][bd]) * QMF_RE(buffer[offset-2][bd]); |
261 | | #endif |
262 | | RE(ac->r01) = r01; |
263 | | RE(ac->r02) = r02; |
264 | | RE(ac->r11) = r11; |
265 | | |
266 | | ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_F(MUL_R(RE(ac->r12), RE(ac->r12)), rel); |
267 | | } |
268 | | #else |
269 | | static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][64], |
270 | | uint8_t bd, uint8_t len) |
271 | 160k | { |
272 | 160k | real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0; |
273 | 160k | real_t temp1_r, temp1_i, temp2_r, temp2_i, temp3_r, temp3_i, temp4_r, temp4_i, temp5_r, temp5_i; |
274 | | #ifdef FIXED_POINT |
275 | 73.5k | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); |
276 | | uint32_t mask, exp; |
277 | | real_t half; |
278 | | #else |
279 | | const real_t rel = 1 / (1 + 1e-6f); |
280 | | #endif |
281 | 160k | int8_t j; |
282 | 160k | uint8_t offset = sbr->tHFAdj; |
283 | | |
284 | | #ifdef FIXED_POINT |
285 | | mask = 0; |
286 | | |
287 | 2.99M | for (j = (offset-2); j < (len + offset); j++) |
288 | 2.91M | { |
289 | 2.91M | real_t x; |
290 | 2.91M | x = QMF_RE(buffer[j][bd])>>REAL_BITS; |
291 | 2.91M | mask |= x ^ (x >> 31); |
292 | 2.91M | x = QMF_IM(buffer[j][bd])>>REAL_BITS; |
293 | 2.91M | mask |= x ^ (x >> 31); |
294 | 2.91M | } |
295 | | |
296 | | exp = wl_min_lzc(mask); |
297 | | |
298 | | /* All-zero input. */ |
299 | 73.5k | if (exp == 0) { |
300 | 68.7k | RE(ac->r01) = 0; |
301 | 68.7k | IM(ac->r01) = 0; |
302 | 68.7k | RE(ac->r02) = 0; |
303 | 68.7k | IM(ac->r02) = 0; |
304 | 68.7k | RE(ac->r11) = 0; |
305 | | // IM(ac->r11) = 0; // unused |
306 | 68.7k | RE(ac->r12) = 0; |
307 | 68.7k | IM(ac->r12) = 0; |
308 | 68.7k | RE(ac->r22) = 0; |
309 | | // IM(ac->r22) = 0; // unused |
310 | 68.7k | ac->det = 0; |
311 | 68.7k | return; |
312 | 68.7k | } |
313 | | /* Otherwise exp > 0. */ |
314 | | /* improves accuracy */ |
315 | 4.80k | exp -= 1; |
316 | | /* Now exp is 0..31 */ |
317 | 4.80k | half = (1 << exp) >> 1; |
318 | | |
319 | 4.80k | temp2_r = (QMF_RE(buffer[offset-2][bd]) + half) >> exp; |
320 | 4.80k | temp2_i = (QMF_IM(buffer[offset-2][bd]) + half) >> exp; |
321 | 4.80k | temp3_r = (QMF_RE(buffer[offset-1][bd]) + half) >> exp; |
322 | 4.80k | temp3_i = (QMF_IM(buffer[offset-1][bd]) + half) >> exp; |
323 | | // Save these because they are needed after loop |
324 | 4.80k | temp4_r = temp2_r; |
325 | 4.80k | temp4_i = temp2_i; |
326 | 4.80k | temp5_r = temp3_r; |
327 | 4.80k | temp5_i = temp3_i; |
328 | | |
329 | 183k | for (j = offset; j < len + offset; j++) |
330 | 178k | { |
331 | 178k | temp1_r = temp2_r; // temp1_r = (QMF_RE(buffer[offset-2][bd] + (1<<(exp-1))) >> exp; |
332 | 178k | temp1_i = temp2_i; // temp1_i = (QMF_IM(buffer[offset-2][bd] + (1<<(exp-1))) >> exp; |
333 | 178k | temp2_r = temp3_r; // temp2_r = (QMF_RE(buffer[offset-1][bd] + (1<<(exp-1))) >> exp; |
334 | 178k | temp2_i = temp3_i; // temp2_i = (QMF_IM(buffer[offset-1][bd] + (1<<(exp-1))) >> exp; |
335 | 178k | temp3_r = (QMF_RE(buffer[j][bd]) + half) >> exp; |
336 | 178k | temp3_i = (QMF_IM(buffer[j][bd]) + half) >> exp; |
337 | 178k | r01r += MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i); |
338 | 178k | r01i += MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i); |
339 | 178k | r02r += MUL_R(temp3_r, temp1_r) + MUL_R(temp3_i, temp1_i); |
340 | 178k | r02i += MUL_R(temp3_i, temp1_r) - MUL_R(temp3_r, temp1_i); |
341 | 178k | r11r += MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i); |
342 | 178k | } |
343 | | |
344 | | // These are actual values in temporary variable at this point |
345 | | // temp1_r = (QMF_RE(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp; |
346 | | // temp1_i = (QMF_IM(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp; |
347 | | // temp2_r = (QMF_RE(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp; |
348 | | // temp2_i = (QMF_IM(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp; |
349 | | // temp3_r = (QMF_RE(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp; |
350 | | // temp3_i = (QMF_IM(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp; |
351 | | // temp4_r = (QMF_RE(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp; |
352 | | // temp4_i = (QMF_IM(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp; |
353 | | // temp5_r = (QMF_RE(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp; |
354 | | // temp5_i = (QMF_IM(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp; |
355 | | |
356 | 4.80k | RE(ac->r12) = r01r - |
357 | 4.80k | (MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i)) + |
358 | 4.80k | (MUL_R(temp5_r, temp4_r) + MUL_R(temp5_i, temp4_i)); |
359 | 4.80k | IM(ac->r12) = r01i - |
360 | 4.80k | (MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i)) + |
361 | 4.80k | (MUL_R(temp5_i, temp4_r) - MUL_R(temp5_r, temp4_i)); |
362 | 4.80k | RE(ac->r22) = r11r - |
363 | 4.80k | (MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i)) + |
364 | 4.80k | (MUL_R(temp4_r, temp4_r) + MUL_R(temp4_i, temp4_i)); |
365 | | |
366 | | #else |
367 | | |
368 | 87.1k | temp2_r = QMF_RE(buffer[offset-2][bd]); |
369 | 87.1k | temp2_i = QMF_IM(buffer[offset-2][bd]); |
370 | 87.1k | temp3_r = QMF_RE(buffer[offset-1][bd]); |
371 | 87.1k | temp3_i = QMF_IM(buffer[offset-1][bd]); |
372 | | // Save these because they are needed after loop |
373 | | temp4_r = temp2_r; |
374 | | temp4_i = temp2_i; |
375 | | temp5_r = temp3_r; |
376 | | temp5_i = temp3_i; |
377 | | |
378 | 3.36M | for (j = offset; j < len + offset; j++) |
379 | 3.28M | { |
380 | 3.28M | temp1_r = temp2_r; // temp1_r = QMF_RE(buffer[j-2][bd]; |
381 | 3.28M | temp1_i = temp2_i; // temp1_i = QMF_IM(buffer[j-2][bd]; |
382 | 3.28M | temp2_r = temp3_r; // temp2_r = QMF_RE(buffer[j-1][bd]; |
383 | 3.28M | temp2_i = temp3_i; // temp2_i = QMF_IM(buffer[j-1][bd]; |
384 | 3.28M | temp3_r = QMF_RE(buffer[j][bd]); |
385 | 3.28M | temp3_i = QMF_IM(buffer[j][bd]); |
386 | 3.28M | r01r += temp3_r * temp2_r + temp3_i * temp2_i; |
387 | 3.28M | r01i += temp3_i * temp2_r - temp3_r * temp2_i; |
388 | 3.28M | r02r += temp3_r * temp1_r + temp3_i * temp1_i; |
389 | 3.28M | r02i += temp3_i * temp1_r - temp3_r * temp1_i; |
390 | 3.28M | r11r += temp2_r * temp2_r + temp2_i * temp2_i; |
391 | 3.28M | } |
392 | | |
393 | | // These are actual values in temporary variable at this point |
394 | | // temp1_r = QMF_RE(buffer[len+offset-1-2][bd]; |
395 | | // temp1_i = QMF_IM(buffer[len+offset-1-2][bd]; |
396 | | // temp2_r = QMF_RE(buffer[len+offset-1-1][bd]; |
397 | | // temp2_i = QMF_IM(buffer[len+offset-1-1][bd]; |
398 | | // temp3_r = QMF_RE(buffer[len+offset-1][bd]); |
399 | | // temp3_i = QMF_IM(buffer[len+offset-1][bd]); |
400 | | // temp4_r = QMF_RE(buffer[offset-2][bd]); |
401 | | // temp4_i = QMF_IM(buffer[offset-2][bd]); |
402 | | // temp5_r = QMF_RE(buffer[offset-1][bd]); |
403 | | // temp5_i = QMF_IM(buffer[offset-1][bd]); |
404 | | |
405 | 87.1k | RE(ac->r12) = r01r - |
406 | | (temp3_r * temp2_r + temp3_i * temp2_i) + |
407 | | (temp5_r * temp4_r + temp5_i * temp4_i); |
408 | 87.1k | IM(ac->r12) = r01i - |
409 | | (temp3_i * temp2_r - temp3_r * temp2_i) + |
410 | | (temp5_i * temp4_r - temp5_r * temp4_i); |
411 | 87.1k | RE(ac->r22) = r11r - |
412 | | (temp2_r * temp2_r + temp2_i * temp2_i) + |
413 | | (temp4_r * temp4_r + temp4_i * temp4_i); |
414 | | |
415 | | #endif |
416 | | |
417 | 91.9k | RE(ac->r01) = r01r; |
418 | 91.9k | IM(ac->r01) = r01i; |
419 | 91.9k | RE(ac->r02) = r02r; |
420 | 91.9k | IM(ac->r02) = r02i; |
421 | 91.9k | RE(ac->r11) = r11r; |
422 | | |
423 | 91.9k | ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_F(rel, (MUL_R(RE(ac->r12), RE(ac->r12)) + MUL_R(IM(ac->r12), IM(ac->r12)))); |
424 | 4.80k | } sbr_hfgen.c:auto_correlation Line | Count | Source | 271 | 73.5k | { | 272 | 73.5k | real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0; | 273 | 73.5k | real_t temp1_r, temp1_i, temp2_r, temp2_i, temp3_r, temp3_i, temp4_r, temp4_i, temp5_r, temp5_i; | 274 | 73.5k | #ifdef FIXED_POINT | 275 | 73.5k | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); | 276 | 73.5k | uint32_t mask, exp; | 277 | 73.5k | real_t half; | 278 | | #else | 279 | | const real_t rel = 1 / (1 + 1e-6f); | 280 | | #endif | 281 | 73.5k | int8_t j; | 282 | 73.5k | uint8_t offset = sbr->tHFAdj; | 283 | | | 284 | 73.5k | #ifdef FIXED_POINT | 285 | 73.5k | mask = 0; | 286 | | | 287 | 2.99M | for (j = (offset-2); j < (len + offset); j++) | 288 | 2.91M | { | 289 | 2.91M | real_t x; | 290 | 2.91M | x = QMF_RE(buffer[j][bd])>>REAL_BITS; | 291 | 2.91M | mask |= x ^ (x >> 31); | 292 | 2.91M | x = QMF_IM(buffer[j][bd])>>REAL_BITS; | 293 | 2.91M | mask |= x ^ (x >> 31); | 294 | 2.91M | } | 295 | | | 296 | 73.5k | exp = wl_min_lzc(mask); | 297 | | | 298 | | /* All-zero input. */ | 299 | 73.5k | if (exp == 0) { | 300 | 68.7k | RE(ac->r01) = 0; | 301 | 68.7k | IM(ac->r01) = 0; | 302 | 68.7k | RE(ac->r02) = 0; | 303 | 68.7k | IM(ac->r02) = 0; | 304 | 68.7k | RE(ac->r11) = 0; | 305 | | // IM(ac->r11) = 0; // unused | 306 | 68.7k | RE(ac->r12) = 0; | 307 | 68.7k | IM(ac->r12) = 0; | 308 | 68.7k | RE(ac->r22) = 0; | 309 | | // IM(ac->r22) = 0; // unused | 310 | 68.7k | ac->det = 0; | 311 | 68.7k | return; | 312 | 68.7k | } | 313 | | /* Otherwise exp > 0. */ | 314 | | /* improves accuracy */ | 315 | 4.80k | exp -= 1; | 316 | | /* Now exp is 0..31 */ | 317 | 4.80k | half = (1 << exp) >> 1; | 318 | | | 319 | 4.80k | temp2_r = (QMF_RE(buffer[offset-2][bd]) + half) >> exp; | 320 | 4.80k | temp2_i = (QMF_IM(buffer[offset-2][bd]) + half) >> exp; | 321 | 4.80k | temp3_r = (QMF_RE(buffer[offset-1][bd]) + half) >> exp; | 322 | 4.80k | temp3_i = (QMF_IM(buffer[offset-1][bd]) + half) >> exp; | 323 | | // Save these because they are needed after loop | 324 | 4.80k | temp4_r = temp2_r; | 325 | 4.80k | temp4_i = temp2_i; | 326 | 4.80k | temp5_r = temp3_r; | 327 | 4.80k | temp5_i = temp3_i; | 328 | | | 329 | 183k | for (j = offset; j < len + offset; j++) | 330 | 178k | { | 331 | 178k | temp1_r = temp2_r; // temp1_r = (QMF_RE(buffer[offset-2][bd] + (1<<(exp-1))) >> exp; | 332 | 178k | temp1_i = temp2_i; // temp1_i = (QMF_IM(buffer[offset-2][bd] + (1<<(exp-1))) >> exp; | 333 | 178k | temp2_r = temp3_r; // temp2_r = (QMF_RE(buffer[offset-1][bd] + (1<<(exp-1))) >> exp; | 334 | 178k | temp2_i = temp3_i; // temp2_i = (QMF_IM(buffer[offset-1][bd] + (1<<(exp-1))) >> exp; | 335 | 178k | temp3_r = (QMF_RE(buffer[j][bd]) + half) >> exp; | 336 | 178k | temp3_i = (QMF_IM(buffer[j][bd]) + half) >> exp; | 337 | 178k | r01r += MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i); | 338 | 178k | r01i += MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i); | 339 | 178k | r02r += MUL_R(temp3_r, temp1_r) + MUL_R(temp3_i, temp1_i); | 340 | 178k | r02i += MUL_R(temp3_i, temp1_r) - MUL_R(temp3_r, temp1_i); | 341 | 178k | r11r += MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i); | 342 | 178k | } | 343 | | | 344 | | // These are actual values in temporary variable at this point | 345 | | // temp1_r = (QMF_RE(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp; | 346 | | // temp1_i = (QMF_IM(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp; | 347 | | // temp2_r = (QMF_RE(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp; | 348 | | // temp2_i = (QMF_IM(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp; | 349 | | // temp3_r = (QMF_RE(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp; | 350 | | // temp3_i = (QMF_IM(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp; | 351 | | // temp4_r = (QMF_RE(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp; | 352 | | // temp4_i = (QMF_IM(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp; | 353 | | // temp5_r = (QMF_RE(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp; | 354 | | // temp5_i = (QMF_IM(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp; | 355 | | | 356 | 4.80k | RE(ac->r12) = r01r - | 357 | 4.80k | (MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i)) + | 358 | 4.80k | (MUL_R(temp5_r, temp4_r) + MUL_R(temp5_i, temp4_i)); | 359 | 4.80k | IM(ac->r12) = r01i - | 360 | 4.80k | (MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i)) + | 361 | 4.80k | (MUL_R(temp5_i, temp4_r) - MUL_R(temp5_r, temp4_i)); | 362 | 4.80k | RE(ac->r22) = r11r - | 363 | 4.80k | (MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i)) + | 364 | 4.80k | (MUL_R(temp4_r, temp4_r) + MUL_R(temp4_i, temp4_i)); | 365 | | | 366 | | #else | 367 | | | 368 | | temp2_r = QMF_RE(buffer[offset-2][bd]); | 369 | | temp2_i = QMF_IM(buffer[offset-2][bd]); | 370 | | temp3_r = QMF_RE(buffer[offset-1][bd]); | 371 | | temp3_i = QMF_IM(buffer[offset-1][bd]); | 372 | | // Save these because they are needed after loop | 373 | | temp4_r = temp2_r; | 374 | | temp4_i = temp2_i; | 375 | | temp5_r = temp3_r; | 376 | | temp5_i = temp3_i; | 377 | | | 378 | | for (j = offset; j < len + offset; j++) | 379 | | { | 380 | | temp1_r = temp2_r; // temp1_r = QMF_RE(buffer[j-2][bd]; | 381 | | temp1_i = temp2_i; // temp1_i = QMF_IM(buffer[j-2][bd]; | 382 | | temp2_r = temp3_r; // temp2_r = QMF_RE(buffer[j-1][bd]; | 383 | | temp2_i = temp3_i; // temp2_i = QMF_IM(buffer[j-1][bd]; | 384 | | temp3_r = QMF_RE(buffer[j][bd]); | 385 | | temp3_i = QMF_IM(buffer[j][bd]); | 386 | | r01r += temp3_r * temp2_r + temp3_i * temp2_i; | 387 | | r01i += temp3_i * temp2_r - temp3_r * temp2_i; | 388 | | r02r += temp3_r * temp1_r + temp3_i * temp1_i; | 389 | | r02i += temp3_i * temp1_r - temp3_r * temp1_i; | 390 | | r11r += temp2_r * temp2_r + temp2_i * temp2_i; | 391 | | } | 392 | | | 393 | | // These are actual values in temporary variable at this point | 394 | | // temp1_r = QMF_RE(buffer[len+offset-1-2][bd]; | 395 | | // temp1_i = QMF_IM(buffer[len+offset-1-2][bd]; | 396 | | // temp2_r = QMF_RE(buffer[len+offset-1-1][bd]; | 397 | | // temp2_i = QMF_IM(buffer[len+offset-1-1][bd]; | 398 | | // temp3_r = QMF_RE(buffer[len+offset-1][bd]); | 399 | | // temp3_i = QMF_IM(buffer[len+offset-1][bd]); | 400 | | // temp4_r = QMF_RE(buffer[offset-2][bd]); | 401 | | // temp4_i = QMF_IM(buffer[offset-2][bd]); | 402 | | // temp5_r = QMF_RE(buffer[offset-1][bd]); | 403 | | // temp5_i = QMF_IM(buffer[offset-1][bd]); | 404 | | | 405 | | RE(ac->r12) = r01r - | 406 | | (temp3_r * temp2_r + temp3_i * temp2_i) + | 407 | | (temp5_r * temp4_r + temp5_i * temp4_i); | 408 | | IM(ac->r12) = r01i - | 409 | | (temp3_i * temp2_r - temp3_r * temp2_i) + | 410 | | (temp5_i * temp4_r - temp5_r * temp4_i); | 411 | | RE(ac->r22) = r11r - | 412 | | (temp2_r * temp2_r + temp2_i * temp2_i) + | 413 | | (temp4_r * temp4_r + temp4_i * temp4_i); | 414 | | | 415 | | #endif | 416 | | | 417 | 4.80k | RE(ac->r01) = r01r; | 418 | 4.80k | IM(ac->r01) = r01i; | 419 | 4.80k | RE(ac->r02) = r02r; | 420 | 4.80k | IM(ac->r02) = r02i; | 421 | 4.80k | RE(ac->r11) = r11r; | 422 | | | 423 | 4.80k | ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_F(rel, (MUL_R(RE(ac->r12), RE(ac->r12)) + MUL_R(IM(ac->r12), IM(ac->r12)))); | 424 | 4.80k | } |
sbr_hfgen.c:auto_correlation Line | Count | Source | 271 | 87.1k | { | 272 | 87.1k | real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0; | 273 | 87.1k | real_t temp1_r, temp1_i, temp2_r, temp2_i, temp3_r, temp3_i, temp4_r, temp4_i, temp5_r, temp5_i; | 274 | | #ifdef FIXED_POINT | 275 | | const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); | 276 | | uint32_t mask, exp; | 277 | | real_t half; | 278 | | #else | 279 | 87.1k | const real_t rel = 1 / (1 + 1e-6f); | 280 | 87.1k | #endif | 281 | 87.1k | int8_t j; | 282 | 87.1k | uint8_t offset = sbr->tHFAdj; | 283 | | | 284 | | #ifdef FIXED_POINT | 285 | | mask = 0; | 286 | | | 287 | | for (j = (offset-2); j < (len + offset); j++) | 288 | | { | 289 | | real_t x; | 290 | | x = QMF_RE(buffer[j][bd])>>REAL_BITS; | 291 | | mask |= x ^ (x >> 31); | 292 | | x = QMF_IM(buffer[j][bd])>>REAL_BITS; | 293 | | mask |= x ^ (x >> 31); | 294 | | } | 295 | | | 296 | | exp = wl_min_lzc(mask); | 297 | | | 298 | | /* All-zero input. */ | 299 | | if (exp == 0) { | 300 | | RE(ac->r01) = 0; | 301 | | IM(ac->r01) = 0; | 302 | | RE(ac->r02) = 0; | 303 | | IM(ac->r02) = 0; | 304 | | RE(ac->r11) = 0; | 305 | | // IM(ac->r11) = 0; // unused | 306 | | RE(ac->r12) = 0; | 307 | | IM(ac->r12) = 0; | 308 | | RE(ac->r22) = 0; | 309 | | // IM(ac->r22) = 0; // unused | 310 | | ac->det = 0; | 311 | | return; | 312 | | } | 313 | | /* Otherwise exp > 0. */ | 314 | | /* improves accuracy */ | 315 | | exp -= 1; | 316 | | /* Now exp is 0..31 */ | 317 | | half = (1 << exp) >> 1; | 318 | | | 319 | | temp2_r = (QMF_RE(buffer[offset-2][bd]) + half) >> exp; | 320 | | temp2_i = (QMF_IM(buffer[offset-2][bd]) + half) >> exp; | 321 | | temp3_r = (QMF_RE(buffer[offset-1][bd]) + half) >> exp; | 322 | | temp3_i = (QMF_IM(buffer[offset-1][bd]) + half) >> exp; | 323 | | // Save these because they are needed after loop | 324 | | temp4_r = temp2_r; | 325 | | temp4_i = temp2_i; | 326 | | temp5_r = temp3_r; | 327 | | temp5_i = temp3_i; | 328 | | | 329 | | for (j = offset; j < len + offset; j++) | 330 | | { | 331 | | temp1_r = temp2_r; // temp1_r = (QMF_RE(buffer[offset-2][bd] + (1<<(exp-1))) >> exp; | 332 | | temp1_i = temp2_i; // temp1_i = (QMF_IM(buffer[offset-2][bd] + (1<<(exp-1))) >> exp; | 333 | | temp2_r = temp3_r; // temp2_r = (QMF_RE(buffer[offset-1][bd] + (1<<(exp-1))) >> exp; | 334 | | temp2_i = temp3_i; // temp2_i = (QMF_IM(buffer[offset-1][bd] + (1<<(exp-1))) >> exp; | 335 | | temp3_r = (QMF_RE(buffer[j][bd]) + half) >> exp; | 336 | | temp3_i = (QMF_IM(buffer[j][bd]) + half) >> exp; | 337 | | r01r += MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i); | 338 | | r01i += MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i); | 339 | | r02r += MUL_R(temp3_r, temp1_r) + MUL_R(temp3_i, temp1_i); | 340 | | r02i += MUL_R(temp3_i, temp1_r) - MUL_R(temp3_r, temp1_i); | 341 | | r11r += MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i); | 342 | | } | 343 | | | 344 | | // These are actual values in temporary variable at this point | 345 | | // temp1_r = (QMF_RE(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp; | 346 | | // temp1_i = (QMF_IM(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp; | 347 | | // temp2_r = (QMF_RE(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp; | 348 | | // temp2_i = (QMF_IM(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp; | 349 | | // temp3_r = (QMF_RE(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp; | 350 | | // temp3_i = (QMF_IM(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp; | 351 | | // temp4_r = (QMF_RE(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp; | 352 | | // temp4_i = (QMF_IM(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp; | 353 | | // temp5_r = (QMF_RE(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp; | 354 | | // temp5_i = (QMF_IM(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp; | 355 | | | 356 | | RE(ac->r12) = r01r - | 357 | | (MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i)) + | 358 | | (MUL_R(temp5_r, temp4_r) + MUL_R(temp5_i, temp4_i)); | 359 | | IM(ac->r12) = r01i - | 360 | | (MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i)) + | 361 | | (MUL_R(temp5_i, temp4_r) - MUL_R(temp5_r, temp4_i)); | 362 | | RE(ac->r22) = r11r - | 363 | | (MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i)) + | 364 | | (MUL_R(temp4_r, temp4_r) + MUL_R(temp4_i, temp4_i)); | 365 | | | 366 | | #else | 367 | | | 368 | 87.1k | temp2_r = QMF_RE(buffer[offset-2][bd]); | 369 | 87.1k | temp2_i = QMF_IM(buffer[offset-2][bd]); | 370 | 87.1k | temp3_r = QMF_RE(buffer[offset-1][bd]); | 371 | 87.1k | temp3_i = QMF_IM(buffer[offset-1][bd]); | 372 | | // Save these because they are needed after loop | 373 | 87.1k | temp4_r = temp2_r; | 374 | 87.1k | temp4_i = temp2_i; | 375 | 87.1k | temp5_r = temp3_r; | 376 | 87.1k | temp5_i = temp3_i; | 377 | | | 378 | 3.36M | for (j = offset; j < len + offset; j++) | 379 | 3.28M | { | 380 | 3.28M | temp1_r = temp2_r; // temp1_r = QMF_RE(buffer[j-2][bd]; | 381 | 3.28M | temp1_i = temp2_i; // temp1_i = QMF_IM(buffer[j-2][bd]; | 382 | 3.28M | temp2_r = temp3_r; // temp2_r = QMF_RE(buffer[j-1][bd]; | 383 | 3.28M | temp2_i = temp3_i; // temp2_i = QMF_IM(buffer[j-1][bd]; | 384 | 3.28M | temp3_r = QMF_RE(buffer[j][bd]); | 385 | 3.28M | temp3_i = QMF_IM(buffer[j][bd]); | 386 | 3.28M | r01r += temp3_r * temp2_r + temp3_i * temp2_i; | 387 | 3.28M | r01i += temp3_i * temp2_r - temp3_r * temp2_i; | 388 | 3.28M | r02r += temp3_r * temp1_r + temp3_i * temp1_i; | 389 | 3.28M | r02i += temp3_i * temp1_r - temp3_r * temp1_i; | 390 | 3.28M | r11r += temp2_r * temp2_r + temp2_i * temp2_i; | 391 | 3.28M | } | 392 | | | 393 | | // These are actual values in temporary variable at this point | 394 | | // temp1_r = QMF_RE(buffer[len+offset-1-2][bd]; | 395 | | // temp1_i = QMF_IM(buffer[len+offset-1-2][bd]; | 396 | | // temp2_r = QMF_RE(buffer[len+offset-1-1][bd]; | 397 | | // temp2_i = QMF_IM(buffer[len+offset-1-1][bd]; | 398 | | // temp3_r = QMF_RE(buffer[len+offset-1][bd]); | 399 | | // temp3_i = QMF_IM(buffer[len+offset-1][bd]); | 400 | | // temp4_r = QMF_RE(buffer[offset-2][bd]); | 401 | | // temp4_i = QMF_IM(buffer[offset-2][bd]); | 402 | | // temp5_r = QMF_RE(buffer[offset-1][bd]); | 403 | | // temp5_i = QMF_IM(buffer[offset-1][bd]); | 404 | | | 405 | 87.1k | RE(ac->r12) = r01r - | 406 | 87.1k | (temp3_r * temp2_r + temp3_i * temp2_i) + | 407 | 87.1k | (temp5_r * temp4_r + temp5_i * temp4_i); | 408 | 87.1k | IM(ac->r12) = r01i - | 409 | 87.1k | (temp3_i * temp2_r - temp3_r * temp2_i) + | 410 | 87.1k | (temp5_i * temp4_r - temp5_r * temp4_i); | 411 | 87.1k | RE(ac->r22) = r11r - | 412 | 87.1k | (temp2_r * temp2_r + temp2_i * temp2_i) + | 413 | 87.1k | (temp4_r * temp4_r + temp4_i * temp4_i); | 414 | | | 415 | 87.1k | #endif | 416 | | | 417 | 87.1k | RE(ac->r01) = r01r; | 418 | 87.1k | IM(ac->r01) = r01i; | 419 | 87.1k | RE(ac->r02) = r02r; | 420 | 87.1k | IM(ac->r02) = r02i; | 421 | 87.1k | RE(ac->r11) = r11r; | 422 | | | 423 | 87.1k | ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_F(rel, (MUL_R(RE(ac->r12), RE(ac->r12)) + MUL_R(IM(ac->r12), IM(ac->r12)))); | 424 | 87.1k | } |
|
425 | | #endif |
426 | | |
427 | | /* calculate linear prediction coefficients using the covariance method */ |
428 | | #ifndef SBR_LOW_POWER |
429 | | static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], |
430 | | complex_t *alpha_0, complex_t *alpha_1, uint8_t k) |
431 | 160k | { |
432 | 160k | real_t tmp; |
433 | 160k | acorr_coef ac; |
434 | | |
435 | 160k | auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6); |
436 | | |
437 | 160k | if (ac.det == 0) |
438 | 152k | { |
439 | 152k | RE(alpha_1[k]) = 0; |
440 | 152k | IM(alpha_1[k]) = 0; |
441 | 152k | } else { |
442 | | #ifdef FIXED_POINT |
443 | 4.59k | tmp = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))); |
444 | 4.59k | RE(alpha_1[k]) = DIV_R(tmp, ac.det); |
445 | 4.59k | tmp = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))); |
446 | 4.59k | IM(alpha_1[k]) = DIV_R(tmp, ac.det); |
447 | | #else |
448 | 4.04k | tmp = REAL_CONST(1.0) / ac.det; |
449 | 4.04k | RE(alpha_1[k]) = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))) * tmp; |
450 | 4.04k | IM(alpha_1[k]) = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))) * tmp; |
451 | | #endif |
452 | 8.63k | } |
453 | | |
454 | 160k | if (RE(ac.r11) == 0) |
455 | 146k | { |
456 | 146k | RE(alpha_0[k]) = 0; |
457 | 146k | IM(alpha_0[k]) = 0; |
458 | 146k | } else { |
459 | | #ifdef FIXED_POINT |
460 | 4.80k | tmp = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))); |
461 | 4.80k | RE(alpha_0[k]) = DIV_R(tmp, RE(ac.r11)); |
462 | 4.80k | tmp = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))); |
463 | 4.80k | IM(alpha_0[k]) = DIV_R(tmp, RE(ac.r11)); |
464 | | #else |
465 | 9.35k | tmp = 1.0f / RE(ac.r11); |
466 | 9.35k | RE(alpha_0[k]) = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))) * tmp; |
467 | 9.35k | IM(alpha_0[k]) = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))) * tmp; |
468 | | #endif |
469 | 14.1k | } |
470 | | |
471 | | /* Sanity check; important: use "yes" check to filter-out NaN values. */ |
472 | 160k | if ((MUL_R(RE(alpha_0[k]),RE(alpha_0[k])) + MUL_R(IM(alpha_0[k]),IM(alpha_0[k])) <= REAL_CONST(16)) && |
473 | 160k | (MUL_R(RE(alpha_1[k]),RE(alpha_1[k])) + MUL_R(IM(alpha_1[k]),IM(alpha_1[k])) <= REAL_CONST(16))) |
474 | 157k | return; |
475 | | /* Fallback */ |
476 | 3.06k | RE(alpha_0[k]) = 0; |
477 | 3.06k | IM(alpha_0[k]) = 0; |
478 | 3.06k | RE(alpha_1[k]) = 0; |
479 | 3.06k | IM(alpha_1[k]) = 0; |
480 | 3.06k | } sbr_hfgen.c:calc_prediction_coef Line | Count | Source | 431 | 73.5k | { | 432 | 73.5k | real_t tmp; | 433 | 73.5k | acorr_coef ac; | 434 | | | 435 | 73.5k | auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6); | 436 | | | 437 | 73.5k | if (ac.det == 0) | 438 | 68.9k | { | 439 | 68.9k | RE(alpha_1[k]) = 0; | 440 | 68.9k | IM(alpha_1[k]) = 0; | 441 | 68.9k | } else { | 442 | 4.59k | #ifdef FIXED_POINT | 443 | 4.59k | tmp = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))); | 444 | 4.59k | RE(alpha_1[k]) = DIV_R(tmp, ac.det); | 445 | 4.59k | tmp = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))); | 446 | 4.59k | IM(alpha_1[k]) = DIV_R(tmp, ac.det); | 447 | | #else | 448 | | tmp = REAL_CONST(1.0) / ac.det; | 449 | | RE(alpha_1[k]) = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))) * tmp; | 450 | | IM(alpha_1[k]) = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))) * tmp; | 451 | | #endif | 452 | 4.59k | } | 453 | | | 454 | 73.5k | if (RE(ac.r11) == 0) | 455 | 68.7k | { | 456 | 68.7k | RE(alpha_0[k]) = 0; | 457 | 68.7k | IM(alpha_0[k]) = 0; | 458 | 68.7k | } else { | 459 | 4.80k | #ifdef FIXED_POINT | 460 | 4.80k | tmp = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))); | 461 | 4.80k | RE(alpha_0[k]) = DIV_R(tmp, RE(ac.r11)); | 462 | 4.80k | tmp = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))); | 463 | 4.80k | IM(alpha_0[k]) = DIV_R(tmp, RE(ac.r11)); | 464 | | #else | 465 | | tmp = 1.0f / RE(ac.r11); | 466 | | RE(alpha_0[k]) = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))) * tmp; | 467 | | IM(alpha_0[k]) = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))) * tmp; | 468 | | #endif | 469 | 4.80k | } | 470 | | | 471 | | /* Sanity check; important: use "yes" check to filter-out NaN values. */ | 472 | 73.5k | if ((MUL_R(RE(alpha_0[k]),RE(alpha_0[k])) + MUL_R(IM(alpha_0[k]),IM(alpha_0[k])) <= REAL_CONST(16)) && | 473 | 73.5k | (MUL_R(RE(alpha_1[k]),RE(alpha_1[k])) + MUL_R(IM(alpha_1[k]),IM(alpha_1[k])) <= REAL_CONST(16))) | 474 | 72.6k | return; | 475 | | /* Fallback */ | 476 | 872 | RE(alpha_0[k]) = 0; | 477 | 872 | IM(alpha_0[k]) = 0; | 478 | 872 | RE(alpha_1[k]) = 0; | 479 | 872 | IM(alpha_1[k]) = 0; | 480 | 872 | } |
sbr_hfgen.c:calc_prediction_coef Line | Count | Source | 431 | 87.1k | { | 432 | 87.1k | real_t tmp; | 433 | 87.1k | acorr_coef ac; | 434 | | | 435 | 87.1k | auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6); | 436 | | | 437 | 87.1k | if (ac.det == 0) | 438 | 83.1k | { | 439 | 83.1k | RE(alpha_1[k]) = 0; | 440 | 83.1k | IM(alpha_1[k]) = 0; | 441 | 83.1k | } else { | 442 | | #ifdef FIXED_POINT | 443 | | tmp = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))); | 444 | | RE(alpha_1[k]) = DIV_R(tmp, ac.det); | 445 | | tmp = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))); | 446 | | IM(alpha_1[k]) = DIV_R(tmp, ac.det); | 447 | | #else | 448 | 4.04k | tmp = REAL_CONST(1.0) / ac.det; | 449 | 4.04k | RE(alpha_1[k]) = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))) * tmp; | 450 | 4.04k | IM(alpha_1[k]) = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))) * tmp; | 451 | 4.04k | #endif | 452 | 4.04k | } | 453 | | | 454 | 87.1k | if (RE(ac.r11) == 0) | 455 | 77.8k | { | 456 | 77.8k | RE(alpha_0[k]) = 0; | 457 | 77.8k | IM(alpha_0[k]) = 0; | 458 | 77.8k | } else { | 459 | | #ifdef FIXED_POINT | 460 | | tmp = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))); | 461 | | RE(alpha_0[k]) = DIV_R(tmp, RE(ac.r11)); | 462 | | tmp = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))); | 463 | | IM(alpha_0[k]) = DIV_R(tmp, RE(ac.r11)); | 464 | | #else | 465 | 9.35k | tmp = 1.0f / RE(ac.r11); | 466 | 9.35k | RE(alpha_0[k]) = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))) * tmp; | 467 | 9.35k | IM(alpha_0[k]) = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))) * tmp; | 468 | 9.35k | #endif | 469 | 9.35k | } | 470 | | | 471 | | /* Sanity check; important: use "yes" check to filter-out NaN values. */ | 472 | 87.1k | if ((MUL_R(RE(alpha_0[k]),RE(alpha_0[k])) + MUL_R(IM(alpha_0[k]),IM(alpha_0[k])) <= REAL_CONST(16)) && | 473 | 87.1k | (MUL_R(RE(alpha_1[k]),RE(alpha_1[k])) + MUL_R(IM(alpha_1[k]),IM(alpha_1[k])) <= REAL_CONST(16))) | 474 | 84.9k | return; | 475 | | /* Fallback */ | 476 | 2.19k | RE(alpha_0[k]) = 0; | 477 | 2.19k | IM(alpha_0[k]) = 0; | 478 | 2.19k | RE(alpha_1[k]) = 0; | 479 | 2.19k | IM(alpha_1[k]) = 0; | 480 | 2.19k | } |
|
481 | | #else |
482 | | static void calc_prediction_coef_lp(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], |
483 | | complex_t *alpha_0, complex_t *alpha_1, real_t *rxx) |
484 | | { |
485 | | uint8_t k; |
486 | | real_t tmp; |
487 | | acorr_coef ac; |
488 | | |
489 | | for (k = 1; k < sbr->f_master[0]; k++) |
490 | | { |
491 | | auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6); |
492 | | |
493 | | if (ac.det == 0) |
494 | | { |
495 | | RE(alpha_0[k]) = 0; |
496 | | RE(alpha_1[k]) = 0; |
497 | | } else { |
498 | | tmp = MUL_R(RE(ac.r01), RE(ac.r22)) - MUL_R(RE(ac.r12), RE(ac.r02)); |
499 | | RE(alpha_0[k]) = DIV_R(tmp, (-ac.det)); |
500 | | |
501 | | tmp = MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11)); |
502 | | RE(alpha_1[k]) = DIV_R(tmp, ac.det); |
503 | | } |
504 | | |
505 | | if ((RE(alpha_0[k]) >= REAL_CONST(4)) || (RE(alpha_1[k]) >= REAL_CONST(4))) |
506 | | { |
507 | | RE(alpha_0[k]) = REAL_CONST(0); |
508 | | RE(alpha_1[k]) = REAL_CONST(0); |
509 | | } |
510 | | |
511 | | /* reflection coefficient */ |
512 | | if (RE(ac.r11) == 0) |
513 | | { |
514 | | rxx[k] = COEF_CONST(0.0); |
515 | | } else { |
516 | | rxx[k] = DIV_C(RE(ac.r01), RE(ac.r11)); |
517 | | rxx[k] = -rxx[k]; |
518 | | if (rxx[k] > COEF_CONST(1.0)) rxx[k] = COEF_CONST(1.0); |
519 | | if (rxx[k] < COEF_CONST(-1.0)) rxx[k] = COEF_CONST(-1.0); |
520 | | } |
521 | | } |
522 | | } |
523 | | |
524 | | static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg) |
525 | | { |
526 | | uint8_t k; |
527 | | |
528 | | rxx[0] = COEF_CONST(0.0); |
529 | | deg[1] = COEF_CONST(0.0); |
530 | | |
531 | | for (k = 2; k < sbr->k0; k++) |
532 | | { |
533 | | deg[k] = 0.0; |
534 | | |
535 | | if ((k % 2 == 0) && (rxx[k] < COEF_CONST(0.0))) |
536 | | { |
537 | | if (rxx[k-1] < 0.0) |
538 | | { |
539 | | deg[k] = COEF_CONST(1.0); |
540 | | |
541 | | if (rxx[k-2] > COEF_CONST(0.0)) |
542 | | { |
543 | | deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); |
544 | | } |
545 | | } else if (rxx[k-2] > COEF_CONST(0.0)) { |
546 | | deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); |
547 | | } |
548 | | } |
549 | | |
550 | | if ((k % 2 == 1) && (rxx[k] > COEF_CONST(0.0))) |
551 | | { |
552 | | if (rxx[k-1] > COEF_CONST(0.0)) |
553 | | { |
554 | | deg[k] = COEF_CONST(1.0); |
555 | | |
556 | | if (rxx[k-2] < COEF_CONST(0.0)) |
557 | | { |
558 | | deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); |
559 | | } |
560 | | } else if (rxx[k-2] < COEF_CONST(0.0)) { |
561 | | deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); |
562 | | } |
563 | | } |
564 | | } |
565 | | } |
566 | | #endif |
567 | | |
568 | | /* FIXED POINT: bwArray = COEF */ |
569 | | static real_t mapNewBw(uint8_t invf_mode, uint8_t invf_mode_prev) |
570 | 46.9k | { |
571 | 46.9k | switch (invf_mode) |
572 | 46.9k | { |
573 | 7.85k | case 1: /* LOW */ |
574 | 7.85k | if (invf_mode_prev == 0) /* NONE */ |
575 | 6.43k | return COEF_CONST(0.6); |
576 | 1.41k | else |
577 | 1.41k | return COEF_CONST(0.75); |
578 | | |
579 | 6.52k | case 2: /* MID */ |
580 | 6.52k | return COEF_CONST(0.9); |
581 | | |
582 | 9.78k | case 3: /* HIGH */ |
583 | 9.78k | return COEF_CONST(0.98); |
584 | | |
585 | 22.7k | default: /* NONE */ |
586 | 22.7k | if (invf_mode_prev == 1) /* LOW */ |
587 | 333 | return COEF_CONST(0.6); |
588 | 22.4k | else |
589 | 22.4k | return COEF_CONST(0.0); |
590 | 46.9k | } |
591 | 46.9k | } Line | Count | Source | 570 | 20.8k | { | 571 | 20.8k | switch (invf_mode) | 572 | 20.8k | { | 573 | 3.80k | case 1: /* LOW */ | 574 | 3.80k | if (invf_mode_prev == 0) /* NONE */ | 575 | 3.17k | return COEF_CONST(0.6); | 576 | 630 | else | 577 | 630 | return COEF_CONST(0.75); | 578 | | | 579 | 2.50k | case 2: /* MID */ | 580 | 2.50k | return COEF_CONST(0.9); | 581 | | | 582 | 4.43k | case 3: /* HIGH */ | 583 | 4.43k | return COEF_CONST(0.98); | 584 | | | 585 | 10.0k | default: /* NONE */ | 586 | 10.0k | if (invf_mode_prev == 1) /* LOW */ | 587 | 156 | return COEF_CONST(0.6); | 588 | 9.90k | else | 589 | 9.90k | return COEF_CONST(0.0); | 590 | 20.8k | } | 591 | 20.8k | } |
Line | Count | Source | 570 | 26.1k | { | 571 | 26.1k | switch (invf_mode) | 572 | 26.1k | { | 573 | 4.04k | case 1: /* LOW */ | 574 | 4.04k | if (invf_mode_prev == 0) /* NONE */ | 575 | 3.26k | return COEF_CONST(0.6); | 576 | 784 | else | 577 | 784 | return COEF_CONST(0.75); | 578 | | | 579 | 4.01k | case 2: /* MID */ | 580 | 4.01k | return COEF_CONST(0.9); | 581 | | | 582 | 5.35k | case 3: /* HIGH */ | 583 | 5.35k | return COEF_CONST(0.98); | 584 | | | 585 | 12.7k | default: /* NONE */ | 586 | 12.7k | if (invf_mode_prev == 1) /* LOW */ | 587 | 177 | return COEF_CONST(0.6); | 588 | 12.5k | else | 589 | 12.5k | return COEF_CONST(0.0); | 590 | 26.1k | } | 591 | 26.1k | } |
|
592 | | |
593 | | /* FIXED POINT: bwArray = COEF */ |
594 | | static void calc_chirp_factors(sbr_info *sbr, uint8_t ch) |
595 | 24.3k | { |
596 | 24.3k | uint8_t i; |
597 | | |
598 | 71.2k | for (i = 0; i < sbr->N_Q; i++) |
599 | 46.9k | { |
600 | 46.9k | sbr->bwArray[ch][i] = mapNewBw(sbr->bs_invf_mode[ch][i], sbr->bs_invf_mode_prev[ch][i]); |
601 | | |
602 | 46.9k | if (sbr->bwArray[ch][i] < sbr->bwArray_prev[ch][i]) |
603 | 1.00k | sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.75)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.25)); |
604 | 45.9k | else |
605 | 45.9k | sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.90625)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.09375)); |
606 | | |
607 | 46.9k | if (sbr->bwArray[ch][i] < COEF_CONST(0.015625)) |
608 | 21.7k | sbr->bwArray[ch][i] = COEF_CONST(0.0); |
609 | | |
610 | 46.9k | if (sbr->bwArray[ch][i] >= COEF_CONST(0.99609375)) |
611 | 0 | sbr->bwArray[ch][i] = COEF_CONST(0.99609375); |
612 | | |
613 | 46.9k | sbr->bwArray_prev[ch][i] = sbr->bwArray[ch][i]; |
614 | 46.9k | sbr->bs_invf_mode_prev[ch][i] = sbr->bs_invf_mode[ch][i]; |
615 | 46.9k | } |
616 | 24.3k | } sbr_hfgen.c:calc_chirp_factors Line | Count | Source | 595 | 10.1k | { | 596 | 10.1k | uint8_t i; | 597 | | | 598 | 30.9k | for (i = 0; i < sbr->N_Q; i++) | 599 | 20.8k | { | 600 | 20.8k | sbr->bwArray[ch][i] = mapNewBw(sbr->bs_invf_mode[ch][i], sbr->bs_invf_mode_prev[ch][i]); | 601 | | | 602 | 20.8k | if (sbr->bwArray[ch][i] < sbr->bwArray_prev[ch][i]) | 603 | 526 | sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.75)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.25)); | 604 | 20.2k | else | 605 | 20.2k | sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.90625)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.09375)); | 606 | | | 607 | 20.8k | if (sbr->bwArray[ch][i] < COEF_CONST(0.015625)) | 608 | 9.54k | sbr->bwArray[ch][i] = COEF_CONST(0.0); | 609 | | | 610 | 20.8k | if (sbr->bwArray[ch][i] >= COEF_CONST(0.99609375)) | 611 | 0 | sbr->bwArray[ch][i] = COEF_CONST(0.99609375); | 612 | | | 613 | 20.8k | sbr->bwArray_prev[ch][i] = sbr->bwArray[ch][i]; | 614 | 20.8k | sbr->bs_invf_mode_prev[ch][i] = sbr->bs_invf_mode[ch][i]; | 615 | 20.8k | } | 616 | 10.1k | } |
sbr_hfgen.c:calc_chirp_factors Line | Count | Source | 595 | 14.1k | { | 596 | 14.1k | uint8_t i; | 597 | | | 598 | 40.3k | for (i = 0; i < sbr->N_Q; i++) | 599 | 26.1k | { | 600 | 26.1k | sbr->bwArray[ch][i] = mapNewBw(sbr->bs_invf_mode[ch][i], sbr->bs_invf_mode_prev[ch][i]); | 601 | | | 602 | 26.1k | if (sbr->bwArray[ch][i] < sbr->bwArray_prev[ch][i]) | 603 | 483 | sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.75)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.25)); | 604 | 25.6k | else | 605 | 25.6k | sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.90625)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.09375)); | 606 | | | 607 | 26.1k | if (sbr->bwArray[ch][i] < COEF_CONST(0.015625)) | 608 | 12.1k | sbr->bwArray[ch][i] = COEF_CONST(0.0); | 609 | | | 610 | 26.1k | if (sbr->bwArray[ch][i] >= COEF_CONST(0.99609375)) | 611 | 0 | sbr->bwArray[ch][i] = COEF_CONST(0.99609375); | 612 | | | 613 | 26.1k | sbr->bwArray_prev[ch][i] = sbr->bwArray[ch][i]; | 614 | 26.1k | sbr->bs_invf_mode_prev[ch][i] = sbr->bs_invf_mode[ch][i]; | 615 | 26.1k | } | 616 | 14.1k | } |
|
617 | | |
618 | | static void patch_construction(sbr_info *sbr) |
619 | 18.8k | { |
620 | 18.8k | uint8_t i, k; |
621 | 18.8k | uint8_t odd, sb; |
622 | 18.8k | uint8_t msb = sbr->k0; |
623 | 18.8k | uint8_t usb = sbr->kx; |
624 | 18.8k | uint8_t goalSbTab[] = { 21, 23, 32, 43, 46, 64, 85, 93, 128, 0, 0, 0 }; |
625 | | /* (uint8_t)(2.048e6/sbr->sample_rate + 0.5); */ |
626 | 18.8k | uint8_t goalSb = goalSbTab[get_sr_index(sbr->sample_rate)]; |
627 | | |
628 | 18.8k | sbr->noPatches = 0; |
629 | | |
630 | 18.8k | if (goalSb < (sbr->kx + sbr->M)) |
631 | 6.91k | { |
632 | 65.8k | for (i = 0, k = 0; sbr->f_master[i] < goalSb; i++) |
633 | 58.9k | k = i+1; |
634 | 11.9k | } else { |
635 | 11.9k | k = sbr->N_master; |
636 | 11.9k | } |
637 | | |
638 | 18.8k | if (sbr->N_master == 0) |
639 | 0 | { |
640 | 0 | sbr->noPatches = 0; |
641 | 0 | sbr->patchNoSubbands[0] = 0; |
642 | 0 | sbr->patchStartSubband[0] = 0; |
643 | |
|
644 | 0 | return; |
645 | 0 | } |
646 | | |
647 | 18.8k | do |
648 | 43.6k | { |
649 | 43.6k | uint8_t j = k + 1; |
650 | | |
651 | 43.6k | do |
652 | 125k | { |
653 | 125k | j--; |
654 | | |
655 | 125k | sb = sbr->f_master[j]; |
656 | 125k | odd = (sb - 2 + sbr->k0) % 2; |
657 | 125k | } while (sb > (sbr->k0 - 1 + msb - odd)); |
658 | | |
659 | 43.6k | sbr->patchNoSubbands[sbr->noPatches] = max(sb - usb, 0); |
660 | 43.6k | sbr->patchStartSubband[sbr->noPatches] = sbr->k0 - odd - |
661 | 43.6k | sbr->patchNoSubbands[sbr->noPatches]; |
662 | | |
663 | 43.6k | if (sbr->patchNoSubbands[sbr->noPatches] > 0) |
664 | 40.1k | { |
665 | 40.1k | usb = sb; |
666 | 40.1k | msb = sb; |
667 | 40.1k | sbr->noPatches++; |
668 | 40.1k | } else { |
669 | 3.46k | msb = sbr->kx; |
670 | 3.46k | } |
671 | | |
672 | 43.6k | if (sbr->f_master[k] - sb < 3) |
673 | 28.1k | k = sbr->N_master; |
674 | 43.6k | } while (sb != (sbr->kx + sbr->M)); |
675 | | |
676 | 18.8k | if ((sbr->patchNoSubbands[sbr->noPatches-1] < 3) && (sbr->noPatches > 1)) |
677 | 2.97k | { |
678 | 2.97k | sbr->noPatches--; |
679 | 2.97k | } |
680 | | |
681 | 18.8k | sbr->noPatches = min(sbr->noPatches, 5); |
682 | 18.8k | } |
683 | | |
684 | | #endif |