mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-11 22:17:17 +03:00
big merge
This commit is contained in:
195
components/spotify/cspot/bell/libhelix-aac/sbrmath.c
Normal file
195
components/spotify/cspot/bell/libhelix-aac/sbrmath.c
Normal file
@@ -0,0 +1,195 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Source last modified: $Id: sbrmath.c,v 1.1 2005/02/26 01:47:35 jrecker Exp $
|
||||
*
|
||||
* Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
|
||||
*
|
||||
* The contents of this file, and the files included with this file,
|
||||
* are subject to the current version of the RealNetworks Public
|
||||
* Source License (the "RPSL") available at
|
||||
* http://www.helixcommunity.org/content/rpsl unless you have licensed
|
||||
* the file under the current version of the RealNetworks Community
|
||||
* Source License (the "RCSL") available at
|
||||
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
|
||||
* will apply. You may also obtain the license terms directly from
|
||||
* RealNetworks. You may not use this file except in compliance with
|
||||
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
|
||||
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
|
||||
* the rights, obligations and limitations governing use of the
|
||||
* contents of the file.
|
||||
*
|
||||
* This file is part of the Helix DNA Technology. RealNetworks is the
|
||||
* developer of the Original Code and owns the copyrights in the
|
||||
* portions it created.
|
||||
*
|
||||
* This file, and the files included with this file, is distributed
|
||||
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
|
||||
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
|
||||
* ENJOYMENT OR NON-INFRINGEMENT.
|
||||
*
|
||||
* Technology Compatibility Kit Test Suite(s) Location:
|
||||
* http://www.helixcommunity.org/content/tck
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**************************************************************************************
|
||||
* Fixed-point HE-AAC decoder
|
||||
* Jon Recker (jrecker@real.com)
|
||||
* February 2005
|
||||
*
|
||||
* sbrmath.c - fixed-point math functions for SBR
|
||||
**************************************************************************************/
|
||||
|
||||
#include "sbr.h"
|
||||
#include "assembly.h"
|
||||
|
||||
#define Q28_2 0x20000000 /* Q28: 2.0 */
|
||||
#define Q28_15 0x30000000 /* Q28: 1.5 */
|
||||
|
||||
#define NUM_ITER_IRN 5
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: InvRNormalized
|
||||
*
|
||||
* Description: use Newton's method to solve for x = 1/r
|
||||
*
|
||||
* Inputs: r = Q31, range = [0.5, 1) (normalize your inputs to this range)
|
||||
*
|
||||
* Outputs: none
|
||||
*
|
||||
* Return: x = Q29, range ~= [1.0, 2.0]
|
||||
*
|
||||
* Notes: guaranteed to converge and not overflow for any r in [0.5, 1)
|
||||
*
|
||||
* xn+1 = xn - f(xn)/f'(xn)
|
||||
* f(x) = 1/r - x = 0 (find root)
|
||||
* = 1/x - r
|
||||
* f'(x) = -1/x^2
|
||||
*
|
||||
* so xn+1 = xn - (1/xn - r) / (-1/xn^2)
|
||||
* = xn * (2 - r*xn)
|
||||
*
|
||||
* NUM_ITER_IRN = 2, maxDiff = 6.2500e-02 (precision of about 4 bits)
|
||||
* NUM_ITER_IRN = 3, maxDiff = 3.9063e-03 (precision of about 8 bits)
|
||||
* NUM_ITER_IRN = 4, maxDiff = 1.5288e-05 (precision of about 16 bits)
|
||||
* NUM_ITER_IRN = 5, maxDiff = 3.0034e-08 (precision of about 24 bits)
|
||||
**************************************************************************************/
|
||||
int InvRNormalized(int r)
|
||||
{
|
||||
int i, xn, t;
|
||||
|
||||
/* r = [0.5, 1.0)
|
||||
* 1/r = (1.0, 2.0]
|
||||
* so use 1.5 as initial guess
|
||||
*/
|
||||
xn = Q28_15;
|
||||
|
||||
/* xn = xn*(2.0 - r*xn) */
|
||||
for (i = NUM_ITER_IRN; i != 0; i--) {
|
||||
t = MULSHIFT32(r, xn); /* Q31*Q29 = Q28 */
|
||||
t = Q28_2 - t; /* Q28 */
|
||||
xn = MULSHIFT32(xn, t) << 4; /* Q29*Q28 << 4 = Q29 */
|
||||
}
|
||||
|
||||
return xn;
|
||||
}
|
||||
|
||||
#define NUM_TERMS_RPI 5
|
||||
#define LOG2_EXP_INV 0x58b90bfc /* 1/log2(e), Q31 */
|
||||
|
||||
/* invTab[x] = 1/(x+1), format = Q30 */
|
||||
static const int invTab[NUM_TERMS_RPI] PROGMEM = {0x40000000, 0x20000000, 0x15555555, 0x10000000, 0x0ccccccd};
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: RatioPowInv
|
||||
*
|
||||
* Description: use Taylor (MacLaurin) series expansion to calculate (a/b) ^ (1/c)
|
||||
*
|
||||
* Inputs: a = [1, 64], b = [1, 64], c = [1, 64], a >= b
|
||||
*
|
||||
* Outputs: none
|
||||
*
|
||||
* Return: y = Q24, range ~= [0.015625, 64]
|
||||
**************************************************************************************/
|
||||
int RatioPowInv(int a, int b, int c)
|
||||
{
|
||||
int lna, lnb, i, p, t, y;
|
||||
|
||||
if (a < 1 || b < 1 || c < 1 || a > 64 || b > 64 || c > 64 || a < b)
|
||||
return 0;
|
||||
|
||||
lna = MULSHIFT32(log2Tab[a], LOG2_EXP_INV) << 1; /* ln(a), Q28 */
|
||||
lnb = MULSHIFT32(log2Tab[b], LOG2_EXP_INV) << 1; /* ln(b), Q28 */
|
||||
p = (lna - lnb) / c; /* Q28 */
|
||||
|
||||
/* sum in Q24 */
|
||||
y = (1 << 24);
|
||||
t = p >> 4; /* t = p^1 * 1/1! (Q24)*/
|
||||
y += t;
|
||||
|
||||
for (i = 2; i <= NUM_TERMS_RPI; i++) {
|
||||
t = MULSHIFT32(invTab[i-1], t) << 2;
|
||||
t = MULSHIFT32(p, t) << 4; /* t = p^i * 1/i! (Q24) */
|
||||
y += t;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: SqrtFix
|
||||
*
|
||||
* Description: use binary search to calculate sqrt(q)
|
||||
*
|
||||
* Inputs: q = Q30
|
||||
* number of fraction bits in input
|
||||
*
|
||||
* Outputs: number of fraction bits in output
|
||||
*
|
||||
* Return: lo = Q(fBitsOut)
|
||||
*
|
||||
* Notes: absolute precision varies depending on fBitsIn
|
||||
* normalizes input to range [0x200000000, 0x7fffffff] and takes
|
||||
* floor(sqrt(input)), and sets fBitsOut appropriately
|
||||
**************************************************************************************/
|
||||
int SqrtFix(int q, int fBitsIn, int *fBitsOut)
|
||||
{
|
||||
int z, lo, hi, mid;
|
||||
|
||||
if (q <= 0) {
|
||||
*fBitsOut = fBitsIn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* force even fBitsIn */
|
||||
z = fBitsIn & 0x01;
|
||||
q >>= z;
|
||||
fBitsIn -= z;
|
||||
|
||||
/* for max precision, normalize to [0x20000000, 0x7fffffff] */
|
||||
z = (CLZ(q) - 1);
|
||||
z >>= 1;
|
||||
q <<= (2*z);
|
||||
|
||||
/* choose initial bounds */
|
||||
lo = 1;
|
||||
if (q >= 0x10000000)
|
||||
lo = 16384; /* (int)sqrt(0x10000000) */
|
||||
hi = 46340; /* (int)sqrt(0x7fffffff) */
|
||||
|
||||
/* do binary search with 32x32->32 multiply test */
|
||||
do {
|
||||
mid = (lo + hi) >> 1;
|
||||
if (mid*mid > q)
|
||||
hi = mid - 1;
|
||||
else
|
||||
lo = mid + 1;
|
||||
} while (hi >= lo);
|
||||
lo--;
|
||||
|
||||
*fBitsOut = ((fBitsIn + 2*z) >> 1);
|
||||
return lo;
|
||||
}
|
||||
Reference in New Issue
Block a user