You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
5.9 KiB
215 lines
5.9 KiB
/****************************************************************************** |
|
* |
|
* Copyright (C) 2014 The Android Open Source Project |
|
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights |
|
* reserved. |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at: |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
******************************************************************************/ |
|
|
|
/******************************************************************************* |
|
$Revision: #1 $ |
|
******************************************************************************/ |
|
|
|
/** |
|
@file |
|
|
|
Dequantizer for SBC decoder; reconstructs quantized representation of subband |
|
samples. |
|
|
|
@ingroup codec_internal |
|
*/ |
|
|
|
/** |
|
@addtogroup codec_internal |
|
@{ |
|
*/ |
|
|
|
/** |
|
This function is a fixed-point approximation of a modification of the following |
|
dequantization operation defined in the spec, as inferred from section 12.6.4: |
|
|
|
@code |
|
dequant = 2^(scale_factor+1) * ((raw * 2.0 + 1.0) / ((2^bits) - 1) - 1) |
|
|
|
2 <= bits <= 16 |
|
0 <= raw < (2^bits)-1 (the -1 is because quantized values with all 1's are |
|
forbidden) |
|
|
|
-65535 < dequant < 65535 |
|
@endcode |
|
|
|
The code below computes the dequantized value divided by a scaling constant |
|
equal to about 1.38. This constant is chosen to ensure that the entry in the |
|
dequant_long_scaled table for 16 bits is as accurate as possible, since it has |
|
the least relative precision available to it due to its small magnitude. |
|
|
|
This routine outputs in Q16.15 format. |
|
|
|
The helper array dequant_long is defined as follows: |
|
|
|
@code |
|
dequant_long_long[bits] = round(2^31 * 1/((2^bits - 1) / 1.38...) for 2 <= |
|
bits <= 16 |
|
@endcode |
|
|
|
|
|
Additionally, the table entries have the following property: |
|
|
|
@code |
|
dequant_long_scaled[bits] <= 2^31 / ((2^bits - 1)) for 2 <= bits <= 16 |
|
@endcode |
|
|
|
Therefore |
|
|
|
@code |
|
d = 2 * raw + 1 1 <= d <= 2^bits - 2 |
|
|
|
d' = d * dequant_long[bits] |
|
|
|
d * dequant_long_scaled[bits] <= (2^bits - 2) * (2^31 / |
|
(2^bits - 1)) |
|
d * dequant_long_scaled[bits] <= 2^31 * (2^bits - 2)/(2^bits - |
|
1) < 2^31 |
|
@endcode |
|
|
|
Therefore, d' doesn't overflow a signed 32-bit value. |
|
|
|
@code |
|
|
|
d' =~ 2^31 * (raw * 2.0 + 1.0) / (2^bits - 1) / 1.38... |
|
|
|
result = d' - 2^31/1.38... =~ 2^31 * ((raw * 2.0 + 1.0) / (2^bits - 1) - 1) / |
|
1.38... |
|
|
|
result is therefore a scaled approximation to dequant. It remains only to |
|
turn 2^31 into 2^(scale_factor+1). Since we're aiming for Q16.15 format, |
|
this is achieved by shifting right by (15-scale_factor): |
|
|
|
(2^31 * x) >> (15-scale_factor) =~ 2^(31-15+scale_factor) * x = 2^15 * |
|
2^(1+scale_factor) * x |
|
@endcode |
|
|
|
*/ |
|
|
|
#include <oi_codec_sbc_private.h> |
|
|
|
#ifndef SBC_DEQUANT_LONG_SCALED_OFFSET |
|
#define SBC_DEQUANT_LONG_SCALED_OFFSET 1555931970 |
|
#endif |
|
|
|
#ifndef SBC_DEQUANT_LONG_UNSCALED_OFFSET |
|
#define SBC_DEQUANT_LONG_UNSCALED_OFFSET 2147483648 |
|
#endif |
|
|
|
#ifndef SBC_DEQUANT_SCALING_FACTOR |
|
#define SBC_DEQUANT_SCALING_FACTOR 1.38019122262781f |
|
#endif |
|
|
|
const uint32_t dequant_long_scaled[17]; |
|
const uint32_t dequant_long_unscaled[17]; |
|
|
|
/** Scales x by y bits to the right, adding a rounding factor. |
|
*/ |
|
#ifndef SCALE |
|
#define SCALE(x, y) (((x) + (1 << ((y)-1))) >> (y)) |
|
#endif |
|
|
|
#ifdef DEBUG_DEQUANTIZATION |
|
|
|
#include <math.h> |
|
|
|
INLINE float dequant_float(uint32_t raw, OI_UINT scale_factor, OI_UINT bits) { |
|
float result = (1 << (scale_factor + 1)) * |
|
((raw * 2.0f + 1.0f) / ((1 << bits) - 1.0f) - 1.0f); |
|
|
|
result /= SBC_DEQUANT_SCALING_FACTOR; |
|
|
|
/* Unless the encoder screwed up, all correct dequantized values should |
|
* satisfy this inequality. Non-compliant encoders which generate quantized |
|
* values with all 1-bits set can, theoretically, trigger this assert. This |
|
* is unlikely, however, and only an issue in debug mode. |
|
*/ |
|
OI_ASSERT(fabs(result) < 32768 * 1.6); |
|
|
|
return result; |
|
} |
|
|
|
#endif |
|
|
|
INLINE int32_t OI_SBC_Dequant(uint32_t raw, OI_UINT scale_factor, |
|
OI_UINT bits) { |
|
uint32_t d; |
|
int32_t result; |
|
|
|
OI_ASSERT(scale_factor <= 15); |
|
OI_ASSERT(bits <= 16); |
|
|
|
if (bits <= 1) { |
|
return 0; |
|
} |
|
|
|
d = (raw * 2) + 1; |
|
d *= dequant_long_scaled[bits]; |
|
result = d - SBC_DEQUANT_LONG_SCALED_OFFSET; |
|
|
|
#ifdef DEBUG_DEQUANTIZATION |
|
{ |
|
int32_t integerized_float_result; |
|
float float_result; |
|
|
|
float_result = dequant_float(raw, scale_factor, bits); |
|
integerized_float_result = (int32_t)floor(0.5f + float_result * (1 << 15)); |
|
|
|
/* This detects overflow */ |
|
OI_ASSERT(((result >= 0) && (integerized_float_result >= 0)) || |
|
((result <= 0) && (integerized_float_result <= 0))); |
|
} |
|
#endif |
|
return result >> (15 - scale_factor); |
|
} |
|
|
|
/* This version of Dequant does not incorporate the scaling factor of 1.38. It |
|
* is intended for use with implementations of the filterbank which are |
|
* hard-coded into a DSP. Output is Q16.4 format, so that after joint stereo |
|
* processing (which leaves the most significant bit equal to the sign bit if |
|
* the encoder is conformant) the result will fit a 24 bit fixed point signed |
|
* value.*/ |
|
|
|
INLINE int32_t OI_SBC_Dequant_Unscaled(uint32_t raw, OI_UINT scale_factor, |
|
OI_UINT bits) { |
|
uint32_t d; |
|
int32_t result; |
|
|
|
OI_ASSERT(scale_factor <= 15); |
|
OI_ASSERT(bits <= 16); |
|
|
|
if (bits <= 1) { |
|
return 0; |
|
} |
|
if (bits == 16) { |
|
result = (raw << 16) + raw - 0x7fff7fff; |
|
return SCALE(result, 24 - scale_factor); |
|
} |
|
|
|
d = (raw * 2) + 1; |
|
d *= dequant_long_unscaled[bits]; |
|
result = d - 0x80000000; |
|
|
|
return SCALE(result, 24 - scale_factor); |
|
} |
|
|
|
/** |
|
@} |
|
*/
|
|
|