2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
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.
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.
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.
19 ** Any non-GPL usage of this software or parts of this software is strictly
22 ** Commercial non-GPL licensing of this software is possible.
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
28 /* Time/Frequency grid */
37 #include "sbr_syntax.h"
38 #include "sbr_tf_grid.h"
41 /* static function declarations */
43 static int16_t rel_bord_lead(sbr_info
*sbr
, uint8_t ch
, uint8_t l
);
44 static int16_t rel_bord_trail(sbr_info
*sbr
, uint8_t ch
, uint8_t l
);
46 static uint8_t middleBorder(sbr_info
*sbr
, uint8_t ch
);
49 /* function constructs new time border vector */
50 /* first build into temp vector to be able to use previous vector on error */
51 uint8_t envelope_time_border_vector(sbr_info
*sbr
, uint8_t ch
)
55 uint8_t t_E_temp
[6] = {0};
57 t_E_temp
[0] = sbr
->rate
* sbr
->abs_bord_lead
[ch
];
58 t_E_temp
[sbr
->L_E
[ch
]] = sbr
->rate
* sbr
->abs_bord_trail
[ch
];
60 switch (sbr
->bs_frame_class
[ch
])
66 temp
= (int) (sbr
->numTimeSlots
/ 4);
67 t_E_temp
[3] = sbr
->rate
* 3 * temp
;
68 t_E_temp
[2] = sbr
->rate
* 2 * temp
;
69 t_E_temp
[1] = sbr
->rate
* temp
;
72 t_E_temp
[1] = sbr
->rate
* (int) (sbr
->numTimeSlots
/ 2);
82 int8_t i
= sbr
->L_E
[ch
];
83 border
= sbr
->abs_bord_trail
[ch
];
85 for (l
= 0; l
< (sbr
->L_E
[ch
] - 1); l
++)
87 if (border
< sbr
->bs_rel_bord
[ch
][l
])
90 border
-= sbr
->bs_rel_bord
[ch
][l
];
91 t_E_temp
[--i
] = sbr
->rate
* border
;
100 border
= sbr
->abs_bord_lead
[ch
];
102 for (l
= 0; l
< (sbr
->L_E
[ch
] - 1); l
++)
104 border
+= sbr
->bs_rel_bord
[ch
][l
];
106 if (sbr
->rate
* border
+ sbr
->tHFAdj
> sbr
->numTimeSlotsRate
+sbr
->tHFGen
)
109 t_E_temp
[i
++] = sbr
->rate
* border
;
115 if (sbr
->bs_num_rel_0
[ch
])
118 border
= sbr
->abs_bord_lead
[ch
];
120 for (l
= 0; l
< sbr
->bs_num_rel_0
[ch
]; l
++)
122 border
+= sbr
->bs_rel_bord_0
[ch
][l
];
124 if (sbr
->rate
* border
+ sbr
->tHFAdj
> sbr
->numTimeSlotsRate
+sbr
->tHFGen
)
127 t_E_temp
[i
++] = sbr
->rate
* border
;
131 if (sbr
->bs_num_rel_1
[ch
])
133 int8_t i
= sbr
->L_E
[ch
];
134 border
= sbr
->abs_bord_trail
[ch
];
136 for (l
= 0; l
< sbr
->bs_num_rel_1
[ch
]; l
++)
138 if (border
< sbr
->bs_rel_bord_1
[ch
][l
])
141 border
-= sbr
->bs_rel_bord_1
[ch
][l
];
142 t_E_temp
[--i
] = sbr
->rate
* border
;
148 /* no error occured, we can safely use this t_E vector */
149 for (l
= 0; l
< 6; l
++)
151 sbr
->t_E
[ch
][l
] = t_E_temp
[l
];
157 void noise_floor_time_border_vector(sbr_info
*sbr
, uint8_t ch
)
159 sbr
->t_Q
[ch
][0] = sbr
->t_E
[ch
][0];
161 if (sbr
->L_E
[ch
] == 1)
163 sbr
->t_Q
[ch
][1] = sbr
->t_E
[ch
][1];
166 uint8_t index
= middleBorder(sbr
, ch
);
167 sbr
->t_Q
[ch
][1] = sbr
->t_E
[ch
][index
];
168 sbr
->t_Q
[ch
][2] = sbr
->t_E
[ch
][sbr
->L_E
[ch
]];
173 static int16_t rel_bord_lead(sbr_info
*sbr
, uint8_t ch
, uint8_t l
)
178 switch (sbr
->bs_frame_class
[ch
])
181 return sbr
->numTimeSlots
/sbr
->L_E
[ch
];
185 for (i
= 0; i
< l
; i
++)
187 acc
+= sbr
->bs_rel_bord
[ch
][i
];
191 for (i
= 0; i
< l
; i
++)
193 acc
+= sbr
->bs_rel_bord_0
[ch
][i
];
201 static int16_t rel_bord_trail(sbr_info
*sbr
, uint8_t ch
, uint8_t l
)
206 switch (sbr
->bs_frame_class
[ch
])
212 for (i
= 0; i
< l
; i
++)
214 acc
+= sbr
->bs_rel_bord
[ch
][i
];
218 for (i
= 0; i
< l
; i
++)
220 acc
+= sbr
->bs_rel_bord_1
[ch
][i
];
229 static uint8_t middleBorder(sbr_info
*sbr
, uint8_t ch
)
233 switch (sbr
->bs_frame_class
[ch
])
236 retval
= sbr
->L_E
[ch
]/2;
239 if (sbr
->bs_pointer
[ch
] == 0)
241 else if (sbr
->bs_pointer
[ch
] == 1)
242 retval
= sbr
->L_E
[ch
] - 1;
244 retval
= sbr
->bs_pointer
[ch
] - 1;
248 if (sbr
->bs_pointer
[ch
] > 1)
249 retval
= sbr
->L_E
[ch
] + 1 - sbr
->bs_pointer
[ch
];
251 retval
= sbr
->L_E
[ch
] - 1;
255 return (retval
> 0) ? retval
: 0;