wmafixed.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:6k
源码类别:

midi

开发平台:

Unix_Linux

  1. /****************************************************************************
  2.  *             __________               __   ___.
  3.  *   Open      ______    ____   ____ |  | __ |__   _______  ___
  4.  *   Source     |       _//  _ _/ ___|  |/ /| __  /  _   /  /
  5.  *   Jukebox    |    |   (  <_> )  ___|    < | _ (  <_> > <  <
  6.  *   Firmware   |____|_  /____/ ___  >__|_ |___  /____/__/_ 
  7.  *                     /            /     /    /            /
  8.  *
  9.  * Copyright (C) 2007 Michael Giacomelli
  10.  *
  11.  * All files in this archive are subject to the GNU General Public License.
  12.  * See the file COPYING in the source tree root for full license agreement.
  13.  *
  14.  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  15.  * KIND, either express or implied.
  16.  *
  17.  ****************************************************************************/
  18. #include "wmadec.h"
  19. #include "wmafixed.h"
  20. int64_t IntTo64(int x){
  21.     int64_t res = 0;
  22.     unsigned char *p = (unsigned char *)&res;
  23. #ifdef ROCKBOX_BIG_ENDIAN
  24.     p[5] = x & 0xff;
  25.     p[4] = (x & 0xff00)>>8;
  26.     p[3] = (x & 0xff0000)>>16;
  27.     p[2] = (x & 0xff000000)>>24;
  28. #else
  29.     p[2] = x & 0xff;
  30.     p[3] = (x & 0xff00)>>8;
  31.     p[4] = (x & 0xff0000)>>16;
  32.     p[5] = (x & 0xff000000)>>24;
  33. #endif
  34.     return res;
  35. }
  36. int IntFrom64(int64_t x)
  37. {
  38.     int res = 0;
  39.     unsigned char *p = (unsigned char *)&x;
  40. #ifdef ROCKBOX_BIG_ENDIAN
  41.     res = p[5] | (p[4]<<8) | (p[3]<<16) | (p[2]<<24);
  42. #else
  43.     res = p[2] | (p[3]<<8) | (p[4]<<16) | (p[5]<<24);
  44. #endif
  45.     return res;
  46. }
  47. int32_t Fixed32From64(int64_t x)
  48. {
  49.   return x & 0xFFFFFFFF;
  50. }
  51. int64_t Fixed32To64(int32_t x)
  52. {
  53.   return (int64_t)x;
  54. }
  55. /*
  56.  * Not performance senstitive code here
  57.  */
  58. int64_t fixmul64byfixed(int64_t x, int32_t y)
  59. {
  60.     return (x * y);
  61. /*  return (int64_t) fixmul32(Fixed32From64(x),y); */
  62. }
  63. int32_t fixdiv32(int32_t x, int32_t y)
  64. {
  65.     int64_t temp;
  66.     if(x == 0)
  67.         return 0;
  68.     if(y == 0)
  69.         return 0x7fffffff;
  70.     temp = x;
  71.     temp <<= PRECISION;
  72.     return (int32_t)(temp / y);
  73. }
  74. int64_t fixdiv64(int64_t x, int64_t y)
  75. {
  76.     int64_t temp;
  77.     if(x == 0)
  78.         return 0;
  79.     if(y == 0)
  80.         return 0x07ffffffffffffffLL;
  81.     temp = x;
  82.     temp <<= PRECISION64;
  83.     return (int64_t)(temp / y);
  84. }
  85. int32_t fixsqrt32(int32_t x)
  86. {
  87.     unsigned long r = 0, s, v = (unsigned long)x;
  88. #define STEP(k) s = r + (1 << k * 2); r >>= 1; 
  89.     if (s <= v) { v -= s; r |= (1 << k * 2); }
  90.     STEP(15);
  91.     STEP(14);
  92.     STEP(13);
  93.     STEP(12);
  94.     STEP(11);
  95.     STEP(10);
  96.     STEP(9);
  97.     STEP(8);
  98.     STEP(7);
  99.     STEP(6);
  100.     STEP(5);
  101.     STEP(4);
  102.     STEP(3);
  103.     STEP(2);
  104.     STEP(1);
  105.     STEP(0);
  106. #undef STEP
  107.     return (int32_t)(r << (PRECISION >> 1));
  108. }
  109. /* Inverse gain of circular cordic rotation in s0.31 format. */
  110. static const long cordic_circular_gain = 0xb2458939; /* 0.607252929 */
  111. /* Table of values of atan(2^-i) in 0.32 format fractions of pi where pi = 0xffffffff / 2 */
  112. static const unsigned long atan_table[] = {
  113.     0x1fffffff, /* +0.785398163 (or pi/4) */
  114.     0x12e4051d, /* +0.463647609 */
  115.     0x09fb385b, /* +0.244978663 */
  116.     0x051111d4, /* +0.124354995 */
  117.     0x028b0d43, /* +0.062418810 */
  118.     0x0145d7e1, /* +0.031239833 */
  119.     0x00a2f61e, /* +0.015623729 */
  120.     0x00517c55, /* +0.007812341 */
  121.     0x0028be53, /* +0.003906230 */
  122.     0x00145f2e, /* +0.001953123 */
  123.     0x000a2f98, /* +0.000976562 */
  124.     0x000517cc, /* +0.000488281 */
  125.     0x00028be6, /* +0.000244141 */
  126.     0x000145f3, /* +0.000122070 */
  127.     0x0000a2f9, /* +0.000061035 */
  128.     0x0000517c, /* +0.000030518 */
  129.     0x000028be, /* +0.000015259 */
  130.     0x0000145f, /* +0.000007629 */
  131.     0x00000a2f, /* +0.000003815 */
  132.     0x00000517, /* +0.000001907 */
  133.     0x0000028b, /* +0.000000954 */
  134.     0x00000145, /* +0.000000477 */
  135.     0x000000a2, /* +0.000000238 */
  136.     0x00000051, /* +0.000000119 */
  137.     0x00000028, /* +0.000000060 */
  138.     0x00000014, /* +0.000000030 */
  139.     0x0000000a, /* +0.000000015 */
  140.     0x00000005, /* +0.000000007 */
  141.     0x00000002, /* +0.000000004 */
  142.     0x00000001, /* +0.000000002 */
  143.     0x00000000, /* +0.000000001 */
  144.     0x00000000, /* +0.000000000 */
  145. };
  146. /*
  147.  *   Below here functions do not use standard fixed precision!
  148.  */
  149. /**
  150.  * Implements sin and cos using CORDIC rotation.
  151.  *
  152.  * @param phase has range from 0 to 0xffffffff, representing 0 and
  153.  *        2*pi respectively.
  154.  * @param cos return address for cos
  155.  * @return sin of phase, value is a signed value from LONG_MIN to LONG_MAX,
  156.  *         representing -1 and 1 respectively.
  157.  *
  158.  *        Gives at least 24 bits precision (last 2-8 bits or so are probably off)
  159.  */
  160. long fsincos(unsigned long phase, int32_t *cos)
  161. {
  162.     int32_t x, x1, y, y1;
  163.     unsigned long z, z1;
  164.     int i;
  165.     /* Setup initial vector */
  166.     x = cordic_circular_gain;
  167.     y = 0;
  168.     z = phase;
  169.     /* The phase has to be somewhere between 0..pi for this to work right */
  170.     if (z < 0xffffffff >> 2) {
  171.         /* z in first quadrant, z += pi/2 to correct */
  172.         x = -x;
  173.         z += 0xffffffff >> 2;
  174.     } else if (z < 3 * (0xffffffff >> 2)) {
  175.         /* z in third quadrant, z -= pi/2 to correct */
  176.         z -= 0xffffffff >> 2;
  177.     } else {
  178.         /* z in fourth quadrant, z -= 3pi/2 to correct */
  179.         x = -x;
  180.         z -= 3 * (0xffffffff >> 2);
  181.     }
  182.     /* Each iteration adds roughly 1-bit of extra precision */
  183.     for (i = 0; i < 31; i++) {
  184.         x1 = x >> i;
  185.         y1 = y >> i;
  186.         z1 = atan_table[i];
  187.         /* Decided which direction to rotate vector. Pivot point is pi/2 */
  188.         if (z >= 0xffffffff >> 2) {
  189.             x -= y1;
  190.             y += x1;
  191.             z -= z1;
  192.         } else {
  193.             x += y1;
  194.             y -= x1;
  195.             z += z1;
  196.         }
  197.     }
  198.     if (cos)
  199.         *cos = x;
  200.     return y;
  201. }