blob: 00fcc16130cc1873c4f2370beae5feb39c5f3695
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_tf_grid.c,v 1.20 2008/09/19 22:50:20 menno Exp $ |
29 | **/ |
30 | |
31 | /* Time/Frequency grid */ |
32 | #include <stdlib.h> |
33 | #include "common.h" |
34 | #include "structs.h" |
35 | |
36 | #ifdef SBR_DEC |
37 | |
38 | |
39 | #include "sbr_syntax.h" |
40 | #include "sbr_tf_grid.h" |
41 | |
42 | |
43 | /* static function declarations */ |
44 | #if 0 |
45 | static int16_t rel_bord_lead(sbr_info *sbr, uint8_t ch, uint8_t l); |
46 | static int16_t rel_bord_trail(sbr_info *sbr, uint8_t ch, uint8_t l); |
47 | #endif |
48 | static uint8_t middleBorder(sbr_info *sbr, uint8_t ch); |
49 | |
50 | |
51 | /* function constructs new time border vector */ |
52 | /* first build into temp vector to be able to use previous vector on error */ |
53 | uint8_t envelope_time_border_vector(sbr_info *sbr, uint8_t ch) |
54 | { |
55 | uint8_t l, border, temp; |
56 | uint8_t t_E_temp[6] = {0}; |
57 | |
58 | t_E_temp[0] = sbr->rate * sbr->abs_bord_lead[ch]; |
59 | t_E_temp[sbr->L_E[ch]] = sbr->rate * sbr->abs_bord_trail[ch]; |
60 | |
61 | switch (sbr->bs_frame_class[ch]) { |
62 | case FIXFIX: |
63 | switch (sbr->L_E[ch]) { |
64 | case 4: |
65 | temp = (sbr->numTimeSlots / 4); |
66 | t_E_temp[3] = sbr->rate * 3 * temp; |
67 | t_E_temp[2] = sbr->rate * 2 * temp; |
68 | t_E_temp[1] = sbr->rate * temp; |
69 | break; |
70 | case 2: |
71 | t_E_temp[1] = sbr->rate * (sbr->numTimeSlots / 2); |
72 | break; |
73 | default: |
74 | break; |
75 | } |
76 | break; |
77 | |
78 | case FIXVAR: |
79 | if (sbr->L_E[ch] > 1) { |
80 | int8_t i = sbr->L_E[ch]; |
81 | border = sbr->abs_bord_trail[ch]; |
82 | |
83 | for (l = 0; l < (sbr->L_E[ch] - 1); l++) { |
84 | if (border < sbr->bs_rel_bord[ch][l]) { |
85 | return 1; |
86 | } |
87 | |
88 | border -= sbr->bs_rel_bord[ch][l]; |
89 | t_E_temp[--i] = sbr->rate * border; |
90 | } |
91 | } |
92 | break; |
93 | |
94 | case VARFIX: |
95 | if (sbr->L_E[ch] > 1) { |
96 | int8_t i = 1; |
97 | border = sbr->abs_bord_lead[ch]; |
98 | |
99 | for (l = 0; l < (sbr->L_E[ch] - 1); l++) { |
100 | border += sbr->bs_rel_bord[ch][l]; |
101 | |
102 | if (sbr->rate * border + sbr->tHFAdj > sbr->numTimeSlotsRate + sbr->tHFGen) { |
103 | return 1; |
104 | } |
105 | |
106 | t_E_temp[i++] = sbr->rate * border; |
107 | } |
108 | } |
109 | break; |
110 | |
111 | case VARVAR: |
112 | if (sbr->bs_num_rel_0[ch]) { |
113 | int8_t i = 1; |
114 | border = sbr->abs_bord_lead[ch]; |
115 | |
116 | for (l = 0; l < sbr->bs_num_rel_0[ch]; l++) { |
117 | border += sbr->bs_rel_bord_0[ch][l]; |
118 | |
119 | if (sbr->rate * border + sbr->tHFAdj > sbr->numTimeSlotsRate + sbr->tHFGen) { |
120 | return 1; |
121 | } |
122 | |
123 | t_E_temp[i++] = sbr->rate * border; |
124 | } |
125 | } |
126 | |
127 | if (sbr->bs_num_rel_1[ch]) { |
128 | int8_t i = sbr->L_E[ch]; |
129 | border = sbr->abs_bord_trail[ch]; |
130 | |
131 | for (l = 0; l < sbr->bs_num_rel_1[ch]; l++) { |
132 | if (border < sbr->bs_rel_bord_1[ch][l]) { |
133 | return 1; |
134 | } |
135 | |
136 | border -= sbr->bs_rel_bord_1[ch][l]; |
137 | t_E_temp[--i] = sbr->rate * border; |
138 | } |
139 | } |
140 | break; |
141 | } |
142 | |
143 | /* no error occured, we can safely use this t_E vector */ |
144 | for (l = 0; l < 6; l++) { |
145 | sbr->t_E[ch][l] = t_E_temp[l]; |
146 | } |
147 | |
148 | return 0; |
149 | } |
150 | |
151 | void noise_floor_time_border_vector(sbr_info *sbr, uint8_t ch) |
152 | { |
153 | sbr->t_Q[ch][0] = sbr->t_E[ch][0]; |
154 | |
155 | if (sbr->L_E[ch] == 1) { |
156 | sbr->t_Q[ch][1] = sbr->t_E[ch][1]; |
157 | sbr->t_Q[ch][2] = 0; |
158 | } else { |
159 | uint8_t index = middleBorder(sbr, ch); |
160 | sbr->t_Q[ch][1] = sbr->t_E[ch][index]; |
161 | sbr->t_Q[ch][2] = sbr->t_E[ch][sbr->L_E[ch]]; |
162 | } |
163 | } |
164 | |
165 | #if 0 |
166 | static int16_t rel_bord_lead(sbr_info *sbr, uint8_t ch, uint8_t l) |
167 | { |
168 | uint8_t i; |
169 | int16_t acc = 0; |
170 | |
171 | switch (sbr->bs_frame_class[ch]) { |
172 | case FIXFIX: |
173 | return sbr->numTimeSlots / sbr->L_E[ch]; |
174 | case FIXVAR: |
175 | return 0; |
176 | case VARFIX: |
177 | for (i = 0; i < l; i++) { |
178 | acc += sbr->bs_rel_bord[ch][i]; |
179 | } |
180 | return acc; |
181 | case VARVAR: |
182 | for (i = 0; i < l; i++) { |
183 | acc += sbr->bs_rel_bord_0[ch][i]; |
184 | } |
185 | return acc; |
186 | } |
187 | |
188 | return 0; |
189 | } |
190 | |
191 | static int16_t rel_bord_trail(sbr_info *sbr, uint8_t ch, uint8_t l) |
192 | { |
193 | uint8_t i; |
194 | int16_t acc = 0; |
195 | |
196 | switch (sbr->bs_frame_class[ch]) { |
197 | case FIXFIX: |
198 | case VARFIX: |
199 | return 0; |
200 | case FIXVAR: |
201 | for (i = 0; i < l; i++) { |
202 | acc += sbr->bs_rel_bord[ch][i]; |
203 | } |
204 | return acc; |
205 | case VARVAR: |
206 | for (i = 0; i < l; i++) { |
207 | acc += sbr->bs_rel_bord_1[ch][i]; |
208 | } |
209 | return acc; |
210 | } |
211 | |
212 | return 0; |
213 | } |
214 | #endif |
215 | |
216 | static uint8_t middleBorder(sbr_info *sbr, uint8_t ch) |
217 | { |
218 | int8_t retval = 0; |
219 | |
220 | switch (sbr->bs_frame_class[ch]) { |
221 | case FIXFIX: |
222 | retval = sbr->L_E[ch] / 2; |
223 | break; |
224 | case VARFIX: |
225 | if (sbr->bs_pointer[ch] == 0) { |
226 | retval = 1; |
227 | } else if (sbr->bs_pointer[ch] == 1) { |
228 | retval = sbr->L_E[ch] - 1; |
229 | } else { |
230 | retval = sbr->bs_pointer[ch] - 1; |
231 | } |
232 | break; |
233 | case FIXVAR: |
234 | case VARVAR: |
235 | if (sbr->bs_pointer[ch] > 1) { |
236 | retval = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch]; |
237 | } else { |
238 | retval = sbr->L_E[ch] - 1; |
239 | } |
240 | break; |
241 | } |
242 | |
243 | return (retval > 0) ? retval : 0; |
244 | } |
245 | |
246 | |
247 | #endif |
248 |