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