xref: /btstack/3rd-party/bluedroid/decoder/srce/dequant.c (revision 08b456cdc6b362da4334c9f472b027160c8b3303)
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 /**
25df25739fSMilanka Ringwald  @file
26df25739fSMilanka Ringwald 
27df25739fSMilanka Ringwald  Dequantizer for SBC decoder; reconstructs quantized representation of subband samples.
28df25739fSMilanka Ringwald 
29df25739fSMilanka Ringwald  @ingroup codec_internal
30df25739fSMilanka Ringwald  */
31df25739fSMilanka Ringwald 
32df25739fSMilanka Ringwald /**
33df25739fSMilanka Ringwald @addtogroup codec_internal
34df25739fSMilanka Ringwald @{
35df25739fSMilanka Ringwald */
36df25739fSMilanka Ringwald 
37df25739fSMilanka Ringwald /**
38df25739fSMilanka Ringwald  This function is a fixed-point approximation of a modification of the following
39df25739fSMilanka Ringwald  dequantization operation defined in the spec, as inferred from section 12.6.4:
40df25739fSMilanka Ringwald 
41df25739fSMilanka Ringwald  @code
42df25739fSMilanka Ringwald  dequant = 2^(scale_factor+1) * ((raw * 2.0 + 1.0) / ((2^bits) - 1) - 1)
43df25739fSMilanka Ringwald 
44df25739fSMilanka Ringwald  2 <= bits <= 16
45df25739fSMilanka Ringwald  0 <= raw < (2^bits)-1   (the -1 is because quantized values with all 1's are forbidden)
46df25739fSMilanka Ringwald 
47df25739fSMilanka Ringwald  -65535 < dequant < 65535
48df25739fSMilanka Ringwald  @endcode
49df25739fSMilanka Ringwald 
50df25739fSMilanka Ringwald  The code below computes the dequantized value divided by a scaling constant
51df25739fSMilanka Ringwald  equal to about 1.38. This constant is chosen to ensure that the entry in the
52df25739fSMilanka Ringwald  dequant_long_scaled table for 16 bits is as accurate as possible, since it has
53df25739fSMilanka Ringwald  the least relative precision available to it due to its small magnitude.
54df25739fSMilanka Ringwald 
55df25739fSMilanka Ringwald  This routine outputs in Q16.15 format.
56df25739fSMilanka Ringwald 
57df25739fSMilanka Ringwald  The helper array dequant_long is defined as follows:
58df25739fSMilanka Ringwald 
59df25739fSMilanka Ringwald  @code
60df25739fSMilanka Ringwald  dequant_long_long[bits] = round(2^31 * 1/((2^bits - 1) / 1.38...)  for 2 <= bits <= 16
61df25739fSMilanka Ringwald  @endcode
62df25739fSMilanka Ringwald 
63df25739fSMilanka Ringwald 
64df25739fSMilanka Ringwald  Additionally, the table entries have the following property:
65df25739fSMilanka Ringwald 
66df25739fSMilanka Ringwald  @code
67df25739fSMilanka Ringwald  dequant_long_scaled[bits] <= 2^31 / ((2^bits - 1))  for 2 <= bits <= 16
68df25739fSMilanka Ringwald  @endcode
69df25739fSMilanka Ringwald 
70df25739fSMilanka Ringwald  Therefore
71df25739fSMilanka Ringwald 
72df25739fSMilanka Ringwald  @code
73df25739fSMilanka Ringwald  d = 2 * raw + 1              1 <= d <= 2^bits - 2
74df25739fSMilanka Ringwald 
75df25739fSMilanka Ringwald  d' = d * dequant_long[bits]
76df25739fSMilanka Ringwald 
77df25739fSMilanka Ringwald                   d * dequant_long_scaled[bits] <= (2^bits - 2) * (2^31 / (2^bits - 1))
78df25739fSMilanka Ringwald                   d * dequant_long_scaled[bits] <= 2^31 * (2^bits - 2)/(2^bits - 1) < 2^31
79df25739fSMilanka Ringwald  @endcode
80df25739fSMilanka Ringwald 
81df25739fSMilanka Ringwald  Therefore, d' doesn't overflow a signed 32-bit value.
82df25739fSMilanka Ringwald 
83df25739fSMilanka Ringwald  @code
84df25739fSMilanka Ringwald 
85df25739fSMilanka Ringwald  d' =~ 2^31 * (raw * 2.0 + 1.0) / (2^bits - 1) / 1.38...
86df25739fSMilanka Ringwald 
87df25739fSMilanka Ringwald  result = d' - 2^31/1.38... =~ 2^31 * ((raw * 2.0 + 1.0) / (2^bits - 1) - 1) / 1.38...
88df25739fSMilanka Ringwald 
89df25739fSMilanka Ringwald  result is therefore a scaled approximation to dequant. It remains only to
90df25739fSMilanka Ringwald  turn 2^31 into 2^(scale_factor+1). Since we're aiming for Q16.15 format,
91df25739fSMilanka Ringwald  this is achieved by shifting right by (15-scale_factor):
92df25739fSMilanka Ringwald 
93df25739fSMilanka Ringwald   (2^31 * x) >> (15-scale_factor) =~ 2^(31-15+scale_factor) * x = 2^15 * 2^(1+scale_factor) * x
94df25739fSMilanka Ringwald  @endcode
95df25739fSMilanka Ringwald 
96df25739fSMilanka Ringwald  */
97df25739fSMilanka Ringwald 
98df25739fSMilanka Ringwald #include <oi_codec_sbc_private.h>
99df25739fSMilanka Ringwald 
100df25739fSMilanka Ringwald #ifndef SBC_DEQUANT_LONG_SCALED_OFFSET
101df25739fSMilanka Ringwald #define SBC_DEQUANT_LONG_SCALED_OFFSET 1555931970
102df25739fSMilanka Ringwald #endif
103df25739fSMilanka Ringwald 
104df25739fSMilanka Ringwald #ifndef SBC_DEQUANT_LONG_UNSCALED_OFFSET
105df25739fSMilanka Ringwald #define SBC_DEQUANT_LONG_UNSCALED_OFFSET 2147483648
106df25739fSMilanka Ringwald #endif
107df25739fSMilanka Ringwald 
108df25739fSMilanka Ringwald #ifndef SBC_DEQUANT_SCALING_FACTOR
109df25739fSMilanka Ringwald #define SBC_DEQUANT_SCALING_FACTOR 1.38019122262781f
110df25739fSMilanka Ringwald #endif
111df25739fSMilanka Ringwald 
112df25739fSMilanka Ringwald extern const OI_UINT32 dequant_long_scaled[17];
113df25739fSMilanka Ringwald extern const OI_UINT32 dequant_long_unscaled[17];
114df25739fSMilanka Ringwald 
115df25739fSMilanka Ringwald /** Scales x by y bits to the right, adding a rounding factor.
116df25739fSMilanka Ringwald  */
117df25739fSMilanka Ringwald #ifndef SCALE
118df25739fSMilanka Ringwald #define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
119df25739fSMilanka Ringwald #endif
120df25739fSMilanka Ringwald 
121df25739fSMilanka Ringwald #ifdef DEBUG_DEQUANTIZATION
122df25739fSMilanka Ringwald 
123df25739fSMilanka Ringwald #include <math.h>
124df25739fSMilanka Ringwald 
dequant_float(OI_UINT32 raw,OI_UINT scale_factor,OI_UINT bits)125df25739fSMilanka Ringwald INLINE float dequant_float(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
126df25739fSMilanka Ringwald {
127df25739fSMilanka Ringwald     float result = (1 << (scale_factor+1)) * ((raw * 2.0f + 1.0f) / ((1 << bits) - 1.0f) - 1.0f);
128df25739fSMilanka Ringwald 
129df25739fSMilanka Ringwald     result /= SBC_DEQUANT_SCALING_FACTOR;
130df25739fSMilanka Ringwald 
131df25739fSMilanka Ringwald     /* Unless the encoder screwed up, all correct dequantized values should
132df25739fSMilanka Ringwald      * satisfy this inequality. Non-compliant encoders which generate quantized
133df25739fSMilanka Ringwald      * values with all 1-bits set can, theoretically, trigger this assert. This
134df25739fSMilanka Ringwald      * is unlikely, however, and only an issue in debug mode.
135df25739fSMilanka Ringwald      */
136df25739fSMilanka Ringwald     OI_ASSERT(fabs(result) < 32768 * 1.6);
137df25739fSMilanka Ringwald 
138df25739fSMilanka Ringwald     return result;
139df25739fSMilanka Ringwald }
140df25739fSMilanka Ringwald 
141df25739fSMilanka Ringwald #endif
142df25739fSMilanka Ringwald 
143df25739fSMilanka Ringwald 
OI_SBC_Dequant(OI_UINT32 raw,OI_UINT scale_factor,OI_UINT bits)144df25739fSMilanka Ringwald INLINE OI_INT32 OI_SBC_Dequant(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
145df25739fSMilanka Ringwald {
146df25739fSMilanka Ringwald     OI_UINT32 d;
147df25739fSMilanka Ringwald     OI_INT32 result;
148df25739fSMilanka Ringwald 
149df25739fSMilanka Ringwald     OI_ASSERT(scale_factor <= 15);
150df25739fSMilanka Ringwald     OI_ASSERT(bits <= 16);
151df25739fSMilanka Ringwald 
152df25739fSMilanka Ringwald     if (bits <= 1) {
153df25739fSMilanka Ringwald         return 0;
154df25739fSMilanka Ringwald     }
155df25739fSMilanka Ringwald 
156df25739fSMilanka Ringwald     d = (raw * 2) + 1;
157df25739fSMilanka Ringwald     d *= dequant_long_scaled[bits];
158df25739fSMilanka Ringwald     result = d - SBC_DEQUANT_LONG_SCALED_OFFSET;
159df25739fSMilanka Ringwald 
160df25739fSMilanka Ringwald #ifdef DEBUG_DEQUANTIZATION
161df25739fSMilanka Ringwald     {
162df25739fSMilanka Ringwald         OI_INT32 integerized_float_result;
163df25739fSMilanka Ringwald         float float_result;
164df25739fSMilanka Ringwald 
165df25739fSMilanka Ringwald         float_result = dequant_float(raw, scale_factor, bits);
166df25739fSMilanka Ringwald         integerized_float_result = (OI_INT32)floor(0.5f+float_result * (1 << 15));
167df25739fSMilanka Ringwald 
168df25739fSMilanka Ringwald         /* This detects overflow */
169df25739fSMilanka Ringwald         OI_ASSERT(((result >= 0) && (integerized_float_result >= 0)) ||
170df25739fSMilanka Ringwald                   ((result <= 0) && (integerized_float_result <= 0)));
171df25739fSMilanka Ringwald     }
172df25739fSMilanka Ringwald #endif
173df25739fSMilanka Ringwald     return result >> (15 - scale_factor);
174df25739fSMilanka Ringwald }
175df25739fSMilanka Ringwald 
176df25739fSMilanka Ringwald /* This version of Dequant does not incorporate the scaling factor of 1.38. It
177df25739fSMilanka Ringwald  * is intended for use with implementations of the filterbank which are
178df25739fSMilanka Ringwald  * hard-coded into a DSP. Output is Q16.4 format, so that after joint stereo
179df25739fSMilanka Ringwald  * processing (which leaves the most significant bit equal to the sign bit if
180df25739fSMilanka Ringwald  * the encoder is conformant) the result will fit a 24 bit fixed point signed
181df25739fSMilanka Ringwald  * value.*/
182df25739fSMilanka Ringwald 
183*08b456cdSMilanka Ringwald INLINE OI_INT32 OI_SBC_Dequant_Unscaled(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits);
OI_SBC_Dequant_Unscaled(OI_UINT32 raw,OI_UINT scale_factor,OI_UINT bits)184df25739fSMilanka Ringwald INLINE OI_INT32 OI_SBC_Dequant_Unscaled(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
185df25739fSMilanka Ringwald {
186df25739fSMilanka Ringwald     OI_UINT32 d;
187df25739fSMilanka Ringwald     OI_INT32 result;
188df25739fSMilanka Ringwald 
189df25739fSMilanka Ringwald     OI_ASSERT(scale_factor <= 15);
190df25739fSMilanka Ringwald     OI_ASSERT(bits <= 16);
191df25739fSMilanka Ringwald 
192df25739fSMilanka Ringwald 
193df25739fSMilanka Ringwald     if (bits <= 1) {
194df25739fSMilanka Ringwald         return 0;
195df25739fSMilanka Ringwald     }
196df25739fSMilanka Ringwald     if (bits == 16) {
197df25739fSMilanka Ringwald         result = (raw << 16) + raw - 0x7fff7fff;
198df25739fSMilanka Ringwald         return SCALE(result, 24 - scale_factor);
199df25739fSMilanka Ringwald     }
200df25739fSMilanka Ringwald 
201df25739fSMilanka Ringwald 
202df25739fSMilanka Ringwald     d = (raw * 2) + 1;
203df25739fSMilanka Ringwald     d *= dequant_long_unscaled[bits];
204df25739fSMilanka Ringwald     result = d - 0x80000000;
205df25739fSMilanka Ringwald 
206df25739fSMilanka Ringwald     return SCALE(result, 24 - scale_factor);
207df25739fSMilanka Ringwald }
208df25739fSMilanka Ringwald 
209df25739fSMilanka Ringwald /**
210df25739fSMilanka Ringwald @}
211df25739fSMilanka Ringwald */
212