1df25739fSMilanka Ringwald /******************************************************************************
2df25739fSMilanka Ringwald *
3df25739fSMilanka Ringwald * Copyright (C) 2014 The Android Open Source Project
4df25739fSMilanka Ringwald * Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
5df25739fSMilanka Ringwald *
6df25739fSMilanka Ringwald * Licensed under the Apache License, Version 2.0 (the "License");
7df25739fSMilanka Ringwald * you may not use this file except in compliance with the License.
8df25739fSMilanka Ringwald * You may obtain a copy of the License at:
9df25739fSMilanka Ringwald *
10df25739fSMilanka Ringwald * http://www.apache.org/licenses/LICENSE-2.0
11df25739fSMilanka Ringwald *
12df25739fSMilanka Ringwald * Unless required by applicable law or agreed to in writing, software
13df25739fSMilanka Ringwald * distributed under the License is distributed on an "AS IS" BASIS,
14df25739fSMilanka Ringwald * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15df25739fSMilanka Ringwald * See the License for the specific language governing permissions and
16df25739fSMilanka Ringwald * limitations under the License.
17df25739fSMilanka Ringwald *
18df25739fSMilanka Ringwald ******************************************************************************/
19df25739fSMilanka Ringwald
20df25739fSMilanka Ringwald /**********************************************************************************
21df25739fSMilanka Ringwald $Revision: #1 $
22df25739fSMilanka Ringwald ***********************************************************************************/
23df25739fSMilanka Ringwald
24df25739fSMilanka Ringwald /** @file
25df25739fSMilanka Ringwald @ingroup codec_internal
26df25739fSMilanka Ringwald */
27df25739fSMilanka Ringwald
28df25739fSMilanka Ringwald /**@addgroup codec_internal*/
29df25739fSMilanka Ringwald /**@{*/
30df25739fSMilanka Ringwald
31df25739fSMilanka Ringwald /*
32df25739fSMilanka Ringwald * Performs an 8-point Type-II scaled DCT using the Arai-Agui-Nakajima
33df25739fSMilanka Ringwald * factorization. The scaling factors are folded into the windowing
34df25739fSMilanka Ringwald * constants. 29 adds and 5 16x32 multiplies per 8 samples.
35df25739fSMilanka Ringwald */
36df25739fSMilanka Ringwald
37df25739fSMilanka Ringwald #include "oi_codec_sbc_private.h"
38df25739fSMilanka Ringwald
39df25739fSMilanka Ringwald #define AAN_C4_FIX (759250125)/* S1.30 759250125 0.707107*/
40df25739fSMilanka Ringwald
41df25739fSMilanka Ringwald #define AAN_C6_FIX (410903207)/* S1.30 410903207 0.382683*/
42df25739fSMilanka Ringwald
43df25739fSMilanka Ringwald #define AAN_Q0_FIX (581104888)/* S1.30 581104888 0.541196*/
44df25739fSMilanka Ringwald
45df25739fSMilanka Ringwald #define AAN_Q1_FIX (1402911301)/* S1.30 1402911301 1.306563*/
46df25739fSMilanka Ringwald
47df25739fSMilanka Ringwald /** Scales x by y bits to the right, adding a rounding factor.
48df25739fSMilanka Ringwald */
49df25739fSMilanka Ringwald #ifndef SCALE
50df25739fSMilanka Ringwald #define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
51df25739fSMilanka Ringwald #endif
52df25739fSMilanka Ringwald
53df25739fSMilanka Ringwald /**
54df25739fSMilanka Ringwald * Default C language implementation of a 32x32->32 multiply. This function may
55df25739fSMilanka Ringwald * be replaced by a platform-specific version for speed.
56df25739fSMilanka Ringwald *
57df25739fSMilanka Ringwald * @param u A signed 32-bit multiplicand
58df25739fSMilanka Ringwald * @param v A signed 32-bit multiplier
59df25739fSMilanka Ringwald
60df25739fSMilanka Ringwald * @return A signed 32-bit value corresponding to the 32 most significant bits
61df25739fSMilanka Ringwald * of the 64-bit product of u and v.
62df25739fSMilanka Ringwald */
6308b456cdSMilanka Ringwald INLINE OI_INT32 default_mul_32s_32s_hi(OI_INT32 u, OI_INT32 v);
default_mul_32s_32s_hi(OI_INT32 u,OI_INT32 v)64df25739fSMilanka Ringwald INLINE OI_INT32 default_mul_32s_32s_hi(OI_INT32 u, OI_INT32 v)
65df25739fSMilanka Ringwald {
66df25739fSMilanka Ringwald OI_UINT32 u0, v0;
67df25739fSMilanka Ringwald OI_INT32 u1, v1, w1, w2, t;
68df25739fSMilanka Ringwald
69df25739fSMilanka Ringwald u0 = u & 0xFFFF; u1 = u >> 16;
70df25739fSMilanka Ringwald v0 = v & 0xFFFF; v1 = v >> 16;
71df25739fSMilanka Ringwald t = u0*v0;
72*c1ab6cc1SMatthias Ringwald t = (u1*v0) + ((OI_UINT32)t >> 16);
73df25739fSMilanka Ringwald w1 = t & 0xFFFF;
74df25739fSMilanka Ringwald w2 = t >> 16;
75*c1ab6cc1SMatthias Ringwald w1 = (u0*v1) + w1;
76*c1ab6cc1SMatthias Ringwald return (u1*v1) + w2 + (w1 >> 16);
77df25739fSMilanka Ringwald }
78df25739fSMilanka Ringwald
79df25739fSMilanka Ringwald #define MUL_32S_32S_HI(_x, _y) default_mul_32s_32s_hi(_x, _y)
80df25739fSMilanka Ringwald
81df25739fSMilanka Ringwald
82df25739fSMilanka Ringwald #ifdef DEBUG_DCT
float_dct2_8(float * RESTRICT out,OI_INT32 const * RESTRICT in)83df25739fSMilanka Ringwald PRIVATE void float_dct2_8(float * RESTRICT out, OI_INT32 const *RESTRICT in)
84df25739fSMilanka Ringwald {
85df25739fSMilanka Ringwald #define FIX(x,bits) (((int)floor(0.5f+((x)*((float)(1<<bits)))))/((float)(1<<bits)))
86df25739fSMilanka Ringwald #define FLOAT_BUTTERFLY(x,y) x += y; y = x - (y*2); OI_ASSERT(VALID_INT32(x)); OI_ASSERT(VALID_INT32(y));
87df25739fSMilanka Ringwald #define FLOAT_MULT_DCT(K, sample) (FIX(K,20) * sample)
88df25739fSMilanka Ringwald #define FLOAT_SCALE(x, y) (((x) / (double)(1 << (y))))
89df25739fSMilanka Ringwald
90df25739fSMilanka Ringwald double L00,L01,L02,L03,L04,L05,L06,L07;
91df25739fSMilanka Ringwald double L25;
92df25739fSMilanka Ringwald
93df25739fSMilanka Ringwald double in0,in1,in2,in3;
94df25739fSMilanka Ringwald double in4,in5,in6,in7;
95df25739fSMilanka Ringwald
96df25739fSMilanka Ringwald in0 = FLOAT_SCALE(in[0], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in0));
97df25739fSMilanka Ringwald in1 = FLOAT_SCALE(in[1], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in1));
98df25739fSMilanka Ringwald in2 = FLOAT_SCALE(in[2], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in2));
99df25739fSMilanka Ringwald in3 = FLOAT_SCALE(in[3], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in3));
100df25739fSMilanka Ringwald in4 = FLOAT_SCALE(in[4], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in4));
101df25739fSMilanka Ringwald in5 = FLOAT_SCALE(in[5], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in5));
102df25739fSMilanka Ringwald in6 = FLOAT_SCALE(in[6], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in6));
103df25739fSMilanka Ringwald in7 = FLOAT_SCALE(in[7], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in7));
104df25739fSMilanka Ringwald
105df25739fSMilanka Ringwald L00 = (in0 + in7); OI_ASSERT(VALID_INT32(L00));
106df25739fSMilanka Ringwald L01 = (in1 + in6); OI_ASSERT(VALID_INT32(L01));
107df25739fSMilanka Ringwald L02 = (in2 + in5); OI_ASSERT(VALID_INT32(L02));
108df25739fSMilanka Ringwald L03 = (in3 + in4); OI_ASSERT(VALID_INT32(L03));
109df25739fSMilanka Ringwald
110df25739fSMilanka Ringwald L04 = (in3 - in4); OI_ASSERT(VALID_INT32(L04));
111df25739fSMilanka Ringwald L05 = (in2 - in5); OI_ASSERT(VALID_INT32(L05));
112df25739fSMilanka Ringwald L06 = (in1 - in6); OI_ASSERT(VALID_INT32(L06));
113df25739fSMilanka Ringwald L07 = (in0 - in7); OI_ASSERT(VALID_INT32(L07));
114df25739fSMilanka Ringwald
115df25739fSMilanka Ringwald FLOAT_BUTTERFLY(L00, L03);
116df25739fSMilanka Ringwald FLOAT_BUTTERFLY(L01, L02);
117df25739fSMilanka Ringwald
118df25739fSMilanka Ringwald L02 += L03; OI_ASSERT(VALID_INT32(L02));
119df25739fSMilanka Ringwald
120df25739fSMilanka Ringwald L02 = FLOAT_MULT_DCT(AAN_C4_FLOAT, L02); OI_ASSERT(VALID_INT32(L02));
121df25739fSMilanka Ringwald
122df25739fSMilanka Ringwald FLOAT_BUTTERFLY(L00, L01);
123df25739fSMilanka Ringwald
124df25739fSMilanka Ringwald out[0] = (float)FLOAT_SCALE(L00, DCTII_8_SHIFT_0); OI_ASSERT(VALID_INT16(out[0]));
125df25739fSMilanka Ringwald out[4] = (float)FLOAT_SCALE(L01, DCTII_8_SHIFT_4); OI_ASSERT(VALID_INT16(out[4]));
126df25739fSMilanka Ringwald
127df25739fSMilanka Ringwald FLOAT_BUTTERFLY(L03, L02);
128df25739fSMilanka Ringwald out[6] = (float)FLOAT_SCALE(L02, DCTII_8_SHIFT_6); OI_ASSERT(VALID_INT16(out[6]));
129df25739fSMilanka Ringwald out[2] = (float)FLOAT_SCALE(L03, DCTII_8_SHIFT_2); OI_ASSERT(VALID_INT16(out[2]));
130df25739fSMilanka Ringwald
131df25739fSMilanka Ringwald L04 += L05; OI_ASSERT(VALID_INT32(L04));
132df25739fSMilanka Ringwald L05 += L06; OI_ASSERT(VALID_INT32(L05));
133df25739fSMilanka Ringwald L06 += L07; OI_ASSERT(VALID_INT32(L06));
134df25739fSMilanka Ringwald
135df25739fSMilanka Ringwald L04/=2;
136df25739fSMilanka Ringwald L05/=2;
137df25739fSMilanka Ringwald L06/=2;
138df25739fSMilanka Ringwald L07/=2;
139df25739fSMilanka Ringwald
140df25739fSMilanka Ringwald L05 = FLOAT_MULT_DCT(AAN_C4_FLOAT, L05); OI_ASSERT(VALID_INT32(L05));
141df25739fSMilanka Ringwald
142df25739fSMilanka Ringwald L25 = L06 - L04; OI_ASSERT(VALID_INT32(L25));
143df25739fSMilanka Ringwald L25 = FLOAT_MULT_DCT(AAN_C6_FLOAT, L25); OI_ASSERT(VALID_INT32(L25));
144df25739fSMilanka Ringwald
145df25739fSMilanka Ringwald L04 = FLOAT_MULT_DCT(AAN_Q0_FLOAT, L04); OI_ASSERT(VALID_INT32(L04));
146df25739fSMilanka Ringwald L04 -= L25; OI_ASSERT(VALID_INT32(L04));
147df25739fSMilanka Ringwald
148df25739fSMilanka Ringwald L06 = FLOAT_MULT_DCT(AAN_Q1_FLOAT, L06); OI_ASSERT(VALID_INT32(L06));
149df25739fSMilanka Ringwald L06 -= L25; OI_ASSERT(VALID_INT32(L25));
150df25739fSMilanka Ringwald
151df25739fSMilanka Ringwald FLOAT_BUTTERFLY(L07, L05);
152df25739fSMilanka Ringwald
153df25739fSMilanka Ringwald FLOAT_BUTTERFLY(L05, L04);
154df25739fSMilanka Ringwald out[3] = (float)(FLOAT_SCALE(L04, DCTII_8_SHIFT_3-1)); OI_ASSERT(VALID_INT16(out[3]));
155df25739fSMilanka Ringwald out[5] = (float)(FLOAT_SCALE(L05, DCTII_8_SHIFT_5-1)); OI_ASSERT(VALID_INT16(out[5]));
156df25739fSMilanka Ringwald
157df25739fSMilanka Ringwald FLOAT_BUTTERFLY(L07, L06);
158df25739fSMilanka Ringwald out[7] = (float)(FLOAT_SCALE(L06, DCTII_8_SHIFT_7-1)); OI_ASSERT(VALID_INT16(out[7]));
159df25739fSMilanka Ringwald out[1] = (float)(FLOAT_SCALE(L07, DCTII_8_SHIFT_1-1)); OI_ASSERT(VALID_INT16(out[1]));
160df25739fSMilanka Ringwald }
161df25739fSMilanka Ringwald #undef BUTTERFLY
162df25739fSMilanka Ringwald #endif
163df25739fSMilanka Ringwald
164df25739fSMilanka Ringwald
165df25739fSMilanka Ringwald /*
166df25739fSMilanka Ringwald * This function calculates the AAN DCT. Its inputs are in S16.15 format, as
167df25739fSMilanka Ringwald * returned by OI_SBC_Dequant. In practice, abs(in[x]) < 52429.0 / 1.38
168df25739fSMilanka Ringwald * (1244918057 integer). The function it computes is an approximation to the array defined
169df25739fSMilanka Ringwald * by:
170df25739fSMilanka Ringwald *
171df25739fSMilanka Ringwald * diag(aan_s) * AAN= C2
172df25739fSMilanka Ringwald *
173df25739fSMilanka Ringwald * or
174df25739fSMilanka Ringwald *
175df25739fSMilanka Ringwald * AAN = diag(1/aan_s) * C2
176df25739fSMilanka Ringwald *
177df25739fSMilanka Ringwald * where C2 is as it is defined in the comment at the head of this file, and
178df25739fSMilanka Ringwald *
179df25739fSMilanka Ringwald * aan_s[i] = aan_s = 1/(2*cos(i*pi/16)) with i = 1..7, aan_s[0] = 1;
180df25739fSMilanka Ringwald *
181df25739fSMilanka Ringwald * aan_s[i] = [ 1.000 0.510 0.541 0.601 0.707 0.900 1.307 2.563 ]
182df25739fSMilanka Ringwald *
183df25739fSMilanka Ringwald * The output ranges are shown as follows:
184df25739fSMilanka Ringwald *
185df25739fSMilanka Ringwald * Let Y[0..7] = AAN * X[0..7]
186df25739fSMilanka Ringwald *
187df25739fSMilanka Ringwald * Without loss of generality, assume the input vector X consists of elements
188df25739fSMilanka Ringwald * between -1 and 1. The maximum possible value of a given output element occurs
189df25739fSMilanka Ringwald * with some particular combination of input vector elements each of which is -1
190df25739fSMilanka Ringwald * or 1. Consider the computation of Y[i]. Y[i] = sum t=0..7 of AAN[t,i]*X[i]. Y is
191df25739fSMilanka Ringwald * maximized if the sign of X[i] matches the sign of AAN[t,i], ensuring a
192df25739fSMilanka Ringwald * positive contribution to the sum. Equivalently, one may simply sum
193df25739fSMilanka Ringwald * abs(AAN)[t,i] over t to get the maximum possible value of Y[i].
194df25739fSMilanka Ringwald *
195df25739fSMilanka Ringwald * This yields approximately [8.00 10.05 9.66 8.52 8.00 5.70 4.00 2.00]
196df25739fSMilanka Ringwald *
197df25739fSMilanka Ringwald * Given the maximum magnitude sensible input value of +/-37992, this yields the
198df25739fSMilanka Ringwald * following vector of maximum output magnitudes:
199df25739fSMilanka Ringwald *
200df25739fSMilanka Ringwald * [ 303936 381820 367003 323692 303936 216555 151968 75984 ]
201df25739fSMilanka Ringwald *
202df25739fSMilanka Ringwald * Ultimately, these values must fit into 16 bit signed integers, so they must
203df25739fSMilanka Ringwald * be scaled. A non-uniform scaling helps maximize the kept precision. The
204df25739fSMilanka Ringwald * relative number of extra bits of precision maintainable with respect to the
205df25739fSMilanka Ringwald * largest value is given here:
206df25739fSMilanka Ringwald *
207df25739fSMilanka Ringwald * [ 0 0 0 0 0 0 1 2 ]
208df25739fSMilanka Ringwald *
209df25739fSMilanka Ringwald */
21008b456cdSMilanka Ringwald PRIVATE void dct2_8(SBC_BUFFER_T * RESTRICT out, OI_INT32 const *RESTRICT in);
dct2_8(SBC_BUFFER_T * RESTRICT out,OI_INT32 const * RESTRICT in)211df25739fSMilanka Ringwald PRIVATE void dct2_8(SBC_BUFFER_T * RESTRICT out, OI_INT32 const *RESTRICT in)
212df25739fSMilanka Ringwald {
213df25739fSMilanka Ringwald #define BUTTERFLY(x,y) x += y; y = x - (y<<1);
214df25739fSMilanka Ringwald #define FIX_MULT_DCT(K, x) (MUL_32S_32S_HI(K,x)<<2)
215df25739fSMilanka Ringwald
216df25739fSMilanka Ringwald OI_INT32 L00,L01,L02,L03,L04,L05,L06,L07;
217df25739fSMilanka Ringwald OI_INT32 L25;
218df25739fSMilanka Ringwald
219df25739fSMilanka Ringwald OI_INT32 in0,in1,in2,in3;
220df25739fSMilanka Ringwald OI_INT32 in4,in5,in6,in7;
221df25739fSMilanka Ringwald
222df25739fSMilanka Ringwald #if DCTII_8_SHIFT_IN != 0
223df25739fSMilanka Ringwald in0 = SCALE(in[0], DCTII_8_SHIFT_IN);
224df25739fSMilanka Ringwald in1 = SCALE(in[1], DCTII_8_SHIFT_IN);
225df25739fSMilanka Ringwald in2 = SCALE(in[2], DCTII_8_SHIFT_IN);
226df25739fSMilanka Ringwald in3 = SCALE(in[3], DCTII_8_SHIFT_IN);
227df25739fSMilanka Ringwald in4 = SCALE(in[4], DCTII_8_SHIFT_IN);
228df25739fSMilanka Ringwald in5 = SCALE(in[5], DCTII_8_SHIFT_IN);
229df25739fSMilanka Ringwald in6 = SCALE(in[6], DCTII_8_SHIFT_IN);
230df25739fSMilanka Ringwald in7 = SCALE(in[7], DCTII_8_SHIFT_IN);
231df25739fSMilanka Ringwald #else
232df25739fSMilanka Ringwald in0 = in[0];
233df25739fSMilanka Ringwald in1 = in[1];
234df25739fSMilanka Ringwald in2 = in[2];
235df25739fSMilanka Ringwald in3 = in[3];
236df25739fSMilanka Ringwald in4 = in[4];
237df25739fSMilanka Ringwald in5 = in[5];
238df25739fSMilanka Ringwald in6 = in[6];
239df25739fSMilanka Ringwald in7 = in[7];
240df25739fSMilanka Ringwald #endif
241df25739fSMilanka Ringwald
242df25739fSMilanka Ringwald L00 = in0 + in7;
243df25739fSMilanka Ringwald L01 = in1 + in6;
244df25739fSMilanka Ringwald L02 = in2 + in5;
245df25739fSMilanka Ringwald L03 = in3 + in4;
246df25739fSMilanka Ringwald
247df25739fSMilanka Ringwald L04 = in3 - in4;
248df25739fSMilanka Ringwald L05 = in2 - in5;
249df25739fSMilanka Ringwald L06 = in1 - in6;
250df25739fSMilanka Ringwald L07 = in0 - in7;
251df25739fSMilanka Ringwald
252df25739fSMilanka Ringwald BUTTERFLY(L00, L03);
253df25739fSMilanka Ringwald BUTTERFLY(L01, L02);
254df25739fSMilanka Ringwald
255df25739fSMilanka Ringwald L02 += L03;
256df25739fSMilanka Ringwald
257df25739fSMilanka Ringwald L02 = FIX_MULT_DCT(AAN_C4_FIX, L02);
258df25739fSMilanka Ringwald
259df25739fSMilanka Ringwald BUTTERFLY(L00, L01);
260df25739fSMilanka Ringwald
261df25739fSMilanka Ringwald out[0] = (OI_INT16)SCALE(L00, DCTII_8_SHIFT_0);
262df25739fSMilanka Ringwald out[4] = (OI_INT16)SCALE(L01, DCTII_8_SHIFT_4);
263df25739fSMilanka Ringwald
264df25739fSMilanka Ringwald BUTTERFLY(L03, L02);
265df25739fSMilanka Ringwald out[6] = (OI_INT16)SCALE(L02, DCTII_8_SHIFT_6);
266df25739fSMilanka Ringwald out[2] = (OI_INT16)SCALE(L03, DCTII_8_SHIFT_2);
267df25739fSMilanka Ringwald
268df25739fSMilanka Ringwald L04 += L05;
269df25739fSMilanka Ringwald L05 += L06;
270df25739fSMilanka Ringwald L06 += L07;
271df25739fSMilanka Ringwald
272df25739fSMilanka Ringwald L04/=2;
273df25739fSMilanka Ringwald L05/=2;
274df25739fSMilanka Ringwald L06/=2;
275df25739fSMilanka Ringwald L07/=2;
276df25739fSMilanka Ringwald
277df25739fSMilanka Ringwald L05 = FIX_MULT_DCT(AAN_C4_FIX, L05);
278df25739fSMilanka Ringwald
279df25739fSMilanka Ringwald L25 = L06 - L04;
280df25739fSMilanka Ringwald L25 = FIX_MULT_DCT(AAN_C6_FIX, L25);
281df25739fSMilanka Ringwald
282df25739fSMilanka Ringwald L04 = FIX_MULT_DCT(AAN_Q0_FIX, L04);
283df25739fSMilanka Ringwald L04 -= L25;
284df25739fSMilanka Ringwald
285df25739fSMilanka Ringwald L06 = FIX_MULT_DCT(AAN_Q1_FIX, L06);
286df25739fSMilanka Ringwald L06 -= L25;
287df25739fSMilanka Ringwald
288df25739fSMilanka Ringwald BUTTERFLY(L07, L05);
289df25739fSMilanka Ringwald
290df25739fSMilanka Ringwald BUTTERFLY(L05, L04);
291df25739fSMilanka Ringwald out[3] = (OI_INT16)SCALE(L04, DCTII_8_SHIFT_3-1);
292df25739fSMilanka Ringwald out[5] = (OI_INT16)SCALE(L05, DCTII_8_SHIFT_5-1);
293df25739fSMilanka Ringwald
294df25739fSMilanka Ringwald BUTTERFLY(L07, L06);
295df25739fSMilanka Ringwald out[7] = (OI_INT16)SCALE(L06, DCTII_8_SHIFT_7-1);
296df25739fSMilanka Ringwald out[1] = (OI_INT16)SCALE(L07, DCTII_8_SHIFT_1-1);
297df25739fSMilanka Ringwald #undef BUTTERFLY
298df25739fSMilanka Ringwald
299df25739fSMilanka Ringwald #ifdef DEBUG_DCT
300df25739fSMilanka Ringwald {
301df25739fSMilanka Ringwald float float_out[8];
302df25739fSMilanka Ringwald float_dct2_8(float_out, in);
303df25739fSMilanka Ringwald }
304df25739fSMilanka Ringwald #endif
305df25739fSMilanka Ringwald }
306df25739fSMilanka Ringwald
307df25739fSMilanka Ringwald /**@}*/
308