mirror of
				https://github.com/cookiengineer/audacity
				synced 2025-10-31 22:23:54 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			835 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			835 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  TwoLAME: an optimized MPEG Audio Layer Two encoder
 | |
|  *
 | |
|  *  Copyright (C) 2001-2004 Michael Cheng
 | |
|  *  Copyright (C) 2004-2006 The TwoLAME Project
 | |
|  *
 | |
|  *  This library is free software; you can redistribute it and/or
 | |
|  *  modify it under the terms of the GNU Lesser General Public
 | |
|  *  License as published by the Free Software Foundation; either
 | |
|  *  version 2.1 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  *  This library is distributed in the hope that it will be useful,
 | |
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  *  Lesser General Public License for more details.
 | |
|  *
 | |
|  *  You should have received a copy of the GNU Lesser General Public
 | |
|  *  License along with this library; if not, write to the Free Software
 | |
|  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
|  *
 | |
|  *  $Id$
 | |
|  *
 | |
|  */
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
| ** FFT and FHT routines
 | |
| **  Copyright 1988, 1993; Ron Mayer
 | |
| **  
 | |
| **  fht(fz,n);
 | |
| **    Does a hartley transform of "n" points in the array "fz".
 | |
| **    
 | |
| ** NOTE: This routine uses at least 2 patented algorithms, and may be
 | |
| **       under the restrictions of a bunch of different organizations.
 | |
| **       Although I wrote it completely myself; it is kind of a derivative
 | |
| **       of a routine I once authored and released under the GPL, so it
 | |
| **       may fall under the free software foundation's restrictions;
 | |
| **       it was worked on as a Stanford Univ project, so they claim
 | |
| **       some rights to it; it was further optimized at work here, so
 | |
| **       I think this company claims parts of it.  The patents are
 | |
| **       held by R. Bracewell (the FHT algorithm) and O. Buneman (the
 | |
| **       trig generator), both at Stanford Univ.
 | |
| **       If it were up to me, I'd say go do whatever you want with it;
 | |
| **       but it would be polite to give credit to the following people
 | |
| **       if you use this anywhere:
 | |
| **           Euler     - probable inventor of the fourier transform.
 | |
| **           Gauss     - probable inventor of the FFT.
 | |
| **           Hartley   - probable inventor of the hartley transform.
 | |
| **           Buneman   - for a really cool trig generator
 | |
| **           Mayer(me) - for authoring this particular version and
 | |
| **                       including all the optimizations in one package.
 | |
| **       Thanks,
 | |
| **       Ron Mayer; mayer@acuson.com
 | |
| **
 | |
| */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <math.h>
 | |
| 
 | |
| #include "twolame.h"
 | |
| #include "common.h"
 | |
| #include "fft.h"
 | |
| 
 | |
| 
 | |
| 
 | |
| #define	SQRT2		1.4142135623730951454746218587388284504414
 | |
| 
 | |
| 
 | |
| static const FLOAT costab[20] = {
 | |
|     .00000000000000000000000000000000000000000000000000,
 | |
|     .70710678118654752440084436210484903928483593768847,
 | |
|     .92387953251128675612818318939678828682241662586364,
 | |
|     .98078528040323044912618223613423903697393373089333,
 | |
|     .99518472667219688624483695310947992157547486872985,
 | |
|     .99879545620517239271477160475910069444320361470461,
 | |
|     .99969881869620422011576564966617219685006108125772,
 | |
|     .99992470183914454092164649119638322435060646880221,
 | |
|     .99998117528260114265699043772856771617391725094433,
 | |
|     .99999529380957617151158012570011989955298763362218,
 | |
|     .99999882345170190992902571017152601904826792288976,
 | |
|     .99999970586288221916022821773876567711626389934930,
 | |
|     .99999992646571785114473148070738785694820115568892,
 | |
|     .99999998161642929380834691540290971450507605124278,
 | |
|     .99999999540410731289097193313960614895889430318945,
 | |
|     .99999999885102682756267330779455410840053741619428
 | |
| };
 | |
| static const FLOAT sintab[20] = {
 | |
|     1.0000000000000000000000000000000000000000000000000,
 | |
|     .70710678118654752440084436210484903928483593768846,
 | |
|     .38268343236508977172845998403039886676134456248561,
 | |
|     .19509032201612826784828486847702224092769161775195,
 | |
|     .09801714032956060199419556388864184586113667316749,
 | |
|     .04906767432741801425495497694268265831474536302574,
 | |
|     .02454122852291228803173452945928292506546611923944,
 | |
|     .01227153828571992607940826195100321214037231959176,
 | |
|     .00613588464915447535964023459037258091705788631738,
 | |
|     .00306795676296597627014536549091984251894461021344,
 | |
|     .00153398018628476561230369715026407907995486457522,
 | |
|     .00076699031874270452693856835794857664314091945205,
 | |
|     .00038349518757139558907246168118138126339502603495,
 | |
|     .00019174759731070330743990956198900093346887403385,
 | |
|     .00009587379909597734587051721097647635118706561284,
 | |
|     .00004793689960306688454900399049465887274686668768
 | |
| };
 | |
| 
 | |
| /* This is a simplified version for n an even power of 2 */
 | |
| /* MFC: In the case of LayerII encoding, n==1024 always. */
 | |
| 
 | |
| static void fht(FLOAT * fz)
 | |
| {
 | |
|     int i, k, k1, k2, k3, k4, kx;
 | |
|     FLOAT *fi, *fn, *gi;
 | |
|     FLOAT t_c, t_s;
 | |
| 
 | |
|     FLOAT a;
 | |
|     static const struct {
 | |
|         unsigned short k1, k2;
 | |
|     } k1k2tab[8 * 62] = {
 | |
|         {
 | |
|         0x020, 0x010}, {
 | |
|         0x040, 0x008}, {
 | |
|         0x050, 0x028}, {
 | |
|         0x060, 0x018}, {
 | |
|         0x068, 0x058}, {
 | |
|         0x070, 0x038}, {
 | |
|         0x080, 0x004}, {
 | |
|         0x088, 0x044}, {
 | |
|         0x090, 0x024}, {
 | |
|         0x098, 0x064}, {
 | |
|         0x0a0, 0x014}, {
 | |
|         0x0a4, 0x094}, {
 | |
|         0x0a8, 0x054}, {
 | |
|         0x0b0, 0x034}, {
 | |
|         0x0b8, 0x074}, {
 | |
|         0x0c0, 0x00c}, {
 | |
|         0x0c4, 0x08c}, {
 | |
|         0x0c8, 0x04c}, {
 | |
|         0x0d0, 0x02c}, {
 | |
|         0x0d4, 0x0ac}, {
 | |
|         0x0d8, 0x06c}, {
 | |
|         0x0e0, 0x01c}, {
 | |
|         0x0e4, 0x09c}, {
 | |
|         0x0e8, 0x05c}, {
 | |
|         0x0ec, 0x0dc}, {
 | |
|         0x0f0, 0x03c}, {
 | |
|         0x0f4, 0x0bc}, {
 | |
|         0x0f8, 0x07c}, {
 | |
|         0x100, 0x002}, {
 | |
|         0x104, 0x082}, {
 | |
|         0x108, 0x042}, {
 | |
|         0x10c, 0x0c2}, {
 | |
|         0x110, 0x022}, {
 | |
|         0x114, 0x0a2}, {
 | |
|         0x118, 0x062}, {
 | |
|         0x11c, 0x0e2}, {
 | |
|         0x120, 0x012}, {
 | |
|         0x122, 0x112}, {
 | |
|         0x124, 0x092}, {
 | |
|         0x128, 0x052}, {
 | |
|         0x12c, 0x0d2}, {
 | |
|         0x130, 0x032}, {
 | |
|         0x134, 0x0b2}, {
 | |
|         0x138, 0x072}, {
 | |
|         0x13c, 0x0f2}, {
 | |
|         0x140, 0x00a}, {
 | |
|         0x142, 0x10a}, {
 | |
|         0x144, 0x08a}, {
 | |
|         0x148, 0x04a}, {
 | |
|         0x14c, 0x0ca}, {
 | |
|         0x150, 0x02a}, {
 | |
|         0x152, 0x12a}, {
 | |
|         0x154, 0x0aa}, {
 | |
|         0x158, 0x06a}, {
 | |
|         0x15c, 0x0ea}, {
 | |
|         0x160, 0x01a}, {
 | |
|         0x162, 0x11a}, {
 | |
|         0x164, 0x09a}, {
 | |
|         0x168, 0x05a}, {
 | |
|         0x16a, 0x15a}, {
 | |
|         0x16c, 0x0da}, {
 | |
|         0x170, 0x03a}, {
 | |
|         0x172, 0x13a}, {
 | |
|         0x174, 0x0ba}, {
 | |
|         0x178, 0x07a}, {
 | |
|         0x17c, 0x0fa}, {
 | |
|         0x180, 0x006}, {
 | |
|         0x182, 0x106}, {
 | |
|         0x184, 0x086}, {
 | |
|         0x188, 0x046}, {
 | |
|         0x18a, 0x146}, {
 | |
|         0x18c, 0x0c6}, {
 | |
|         0x190, 0x026}, {
 | |
|         0x192, 0x126}, {
 | |
|         0x194, 0x0a6}, {
 | |
|         0x198, 0x066}, {
 | |
|         0x19a, 0x166}, {
 | |
|         0x19c, 0x0e6}, {
 | |
|         0x1a0, 0x016}, {
 | |
|         0x1a2, 0x116}, {
 | |
|         0x1a4, 0x096}, {
 | |
|         0x1a6, 0x196}, {
 | |
|         0x1a8, 0x056}, {
 | |
|         0x1aa, 0x156}, {
 | |
|         0x1ac, 0x0d6}, {
 | |
|         0x1b0, 0x036}, {
 | |
|         0x1b2, 0x136}, {
 | |
|         0x1b4, 0x0b6}, {
 | |
|         0x1b8, 0x076}, {
 | |
|         0x1ba, 0x176}, {
 | |
|         0x1bc, 0x0f6}, {
 | |
|         0x1c0, 0x00e}, {
 | |
|         0x1c2, 0x10e}, {
 | |
|         0x1c4, 0x08e}, {
 | |
|         0x1c6, 0x18e}, {
 | |
|         0x1c8, 0x04e}, {
 | |
|         0x1ca, 0x14e}, {
 | |
|         0x1cc, 0x0ce}, {
 | |
|         0x1d0, 0x02e}, {
 | |
|         0x1d2, 0x12e}, {
 | |
|         0x1d4, 0x0ae}, {
 | |
|         0x1d6, 0x1ae}, {
 | |
|         0x1d8, 0x06e}, {
 | |
|         0x1da, 0x16e}, {
 | |
|         0x1dc, 0x0ee}, {
 | |
|         0x1e0, 0x01e}, {
 | |
|         0x1e2, 0x11e}, {
 | |
|         0x1e4, 0x09e}, {
 | |
|         0x1e6, 0x19e}, {
 | |
|         0x1e8, 0x05e}, {
 | |
|         0x1ea, 0x15e}, {
 | |
|         0x1ec, 0x0de}, {
 | |
|         0x1ee, 0x1de}, {
 | |
|         0x1f0, 0x03e}, {
 | |
|         0x1f2, 0x13e}, {
 | |
|         0x1f4, 0x0be}, {
 | |
|         0x1f6, 0x1be}, {
 | |
|         0x1f8, 0x07e}, {
 | |
|         0x1fa, 0x17e}, {
 | |
|         0x1fc, 0x0fe}, {
 | |
|         0x200, 0x001}, {
 | |
|         0x202, 0x101}, {
 | |
|         0x204, 0x081}, {
 | |
|         0x206, 0x181}, {
 | |
|         0x208, 0x041}, {
 | |
|         0x20a, 0x141}, {
 | |
|         0x20c, 0x0c1}, {
 | |
|         0x20e, 0x1c1}, {
 | |
|         0x210, 0x021}, {
 | |
|         0x212, 0x121}, {
 | |
|         0x214, 0x0a1}, {
 | |
|         0x216, 0x1a1}, {
 | |
|         0x218, 0x061}, {
 | |
|         0x21a, 0x161}, {
 | |
|         0x21c, 0x0e1}, {
 | |
|         0x21e, 0x1e1}, {
 | |
|         0x220, 0x011}, {
 | |
|         0x221, 0x211}, {
 | |
|         0x222, 0x111}, {
 | |
|         0x224, 0x091}, {
 | |
|         0x226, 0x191}, {
 | |
|         0x228, 0x051}, {
 | |
|         0x22a, 0x151}, {
 | |
|         0x22c, 0x0d1}, {
 | |
|         0x22e, 0x1d1}, {
 | |
|         0x230, 0x031}, {
 | |
|         0x232, 0x131}, {
 | |
|         0x234, 0x0b1}, {
 | |
|         0x236, 0x1b1}, {
 | |
|         0x238, 0x071}, {
 | |
|         0x23a, 0x171}, {
 | |
|         0x23c, 0x0f1}, {
 | |
|         0x23e, 0x1f1}, {
 | |
|         0x240, 0x009}, {
 | |
|         0x241, 0x209}, {
 | |
|         0x242, 0x109}, {
 | |
|         0x244, 0x089}, {
 | |
|         0x246, 0x189}, {
 | |
|         0x248, 0x049}, {
 | |
|         0x24a, 0x149}, {
 | |
|         0x24c, 0x0c9}, {
 | |
|         0x24e, 0x1c9}, {
 | |
|         0x250, 0x029}, {
 | |
|         0x251, 0x229}, {
 | |
|         0x252, 0x129}, {
 | |
|         0x254, 0x0a9}, {
 | |
|         0x256, 0x1a9}, {
 | |
|         0x258, 0x069}, {
 | |
|         0x25a, 0x169}, {
 | |
|         0x25c, 0x0e9}, {
 | |
|         0x25e, 0x1e9}, {
 | |
|         0x260, 0x019}, {
 | |
|         0x261, 0x219}, {
 | |
|         0x262, 0x119}, {
 | |
|         0x264, 0x099}, {
 | |
|         0x266, 0x199}, {
 | |
|         0x268, 0x059}, {
 | |
|         0x269, 0x259}, {
 | |
|         0x26a, 0x159}, {
 | |
|         0x26c, 0x0d9}, {
 | |
|         0x26e, 0x1d9}, {
 | |
|         0x270, 0x039}, {
 | |
|         0x271, 0x239}, {
 | |
|         0x272, 0x139}, {
 | |
|         0x274, 0x0b9}, {
 | |
|         0x276, 0x1b9}, {
 | |
|         0x278, 0x079}, {
 | |
|         0x27a, 0x179}, {
 | |
|         0x27c, 0x0f9}, {
 | |
|         0x27e, 0x1f9}, {
 | |
|         0x280, 0x005}, {
 | |
|         0x281, 0x205}, {
 | |
|         0x282, 0x105}, {
 | |
|         0x284, 0x085}, {
 | |
|         0x286, 0x185}, {
 | |
|         0x288, 0x045}, {
 | |
|         0x289, 0x245}, {
 | |
|         0x28a, 0x145}, {
 | |
|         0x28c, 0x0c5}, {
 | |
|         0x28e, 0x1c5}, {
 | |
|         0x290, 0x025}, {
 | |
|         0x291, 0x225}, {
 | |
|         0x292, 0x125}, {
 | |
|         0x294, 0x0a5}, {
 | |
|         0x296, 0x1a5}, {
 | |
|         0x298, 0x065}, {
 | |
|         0x299, 0x265}, {
 | |
|         0x29a, 0x165}, {
 | |
|         0x29c, 0x0e5}, {
 | |
|         0x29e, 0x1e5}, {
 | |
|         0x2a0, 0x015}, {
 | |
|         0x2a1, 0x215}, {
 | |
|         0x2a2, 0x115}, {
 | |
|         0x2a4, 0x095}, {
 | |
|         0x2a5, 0x295}, {
 | |
|         0x2a6, 0x195}, {
 | |
|         0x2a8, 0x055}, {
 | |
|         0x2a9, 0x255}, {
 | |
|         0x2aa, 0x155}, {
 | |
|         0x2ac, 0x0d5}, {
 | |
|         0x2ae, 0x1d5}, {
 | |
|         0x2b0, 0x035}, {
 | |
|         0x2b1, 0x235}, {
 | |
|         0x2b2, 0x135}, {
 | |
|         0x2b4, 0x0b5}, {
 | |
|         0x2b6, 0x1b5}, {
 | |
|         0x2b8, 0x075}, {
 | |
|         0x2b9, 0x275}, {
 | |
|         0x2ba, 0x175}, {
 | |
|         0x2bc, 0x0f5}, {
 | |
|         0x2be, 0x1f5}, {
 | |
|         0x2c0, 0x00d}, {
 | |
|         0x2c1, 0x20d}, {
 | |
|         0x2c2, 0x10d}, {
 | |
|         0x2c4, 0x08d}, {
 | |
|         0x2c5, 0x28d}, {
 | |
|         0x2c6, 0x18d}, {
 | |
|         0x2c8, 0x04d}, {
 | |
|         0x2c9, 0x24d}, {
 | |
|         0x2ca, 0x14d}, {
 | |
|         0x2cc, 0x0cd}, {
 | |
|         0x2ce, 0x1cd}, {
 | |
|         0x2d0, 0x02d}, {
 | |
|         0x2d1, 0x22d}, {
 | |
|         0x2d2, 0x12d}, {
 | |
|         0x2d4, 0x0ad}, {
 | |
|         0x2d5, 0x2ad}, {
 | |
|         0x2d6, 0x1ad}, {
 | |
|         0x2d8, 0x06d}, {
 | |
|         0x2d9, 0x26d}, {
 | |
|         0x2da, 0x16d}, {
 | |
|         0x2dc, 0x0ed}, {
 | |
|         0x2de, 0x1ed}, {
 | |
|         0x2e0, 0x01d}, {
 | |
|         0x2e1, 0x21d}, {
 | |
|         0x2e2, 0x11d}, {
 | |
|         0x2e4, 0x09d}, {
 | |
|         0x2e5, 0x29d}, {
 | |
|         0x2e6, 0x19d}, {
 | |
|         0x2e8, 0x05d}, {
 | |
|         0x2e9, 0x25d}, {
 | |
|         0x2ea, 0x15d}, {
 | |
|         0x2ec, 0x0dd}, {
 | |
|         0x2ed, 0x2dd}, {
 | |
|         0x2ee, 0x1dd}, {
 | |
|         0x2f0, 0x03d}, {
 | |
|         0x2f1, 0x23d}, {
 | |
|         0x2f2, 0x13d}, {
 | |
|         0x2f4, 0x0bd}, {
 | |
|         0x2f5, 0x2bd}, {
 | |
|         0x2f6, 0x1bd}, {
 | |
|         0x2f8, 0x07d}, {
 | |
|         0x2f9, 0x27d}, {
 | |
|         0x2fa, 0x17d}, {
 | |
|         0x2fc, 0x0fd}, {
 | |
|         0x2fe, 0x1fd}, {
 | |
|         0x300, 0x003}, {
 | |
|         0x301, 0x203}, {
 | |
|         0x302, 0x103}, {
 | |
|         0x304, 0x083}, {
 | |
|         0x305, 0x283}, {
 | |
|         0x306, 0x183}, {
 | |
|         0x308, 0x043}, {
 | |
|         0x309, 0x243}, {
 | |
|         0x30a, 0x143}, {
 | |
|         0x30c, 0x0c3}, {
 | |
|         0x30d, 0x2c3}, {
 | |
|         0x30e, 0x1c3}, {
 | |
|         0x310, 0x023}, {
 | |
|         0x311, 0x223}, {
 | |
|         0x312, 0x123}, {
 | |
|         0x314, 0x0a3}, {
 | |
|         0x315, 0x2a3}, {
 | |
|         0x316, 0x1a3}, {
 | |
|         0x318, 0x063}, {
 | |
|         0x319, 0x263}, {
 | |
|         0x31a, 0x163}, {
 | |
|         0x31c, 0x0e3}, {
 | |
|         0x31d, 0x2e3}, {
 | |
|         0x31e, 0x1e3}, {
 | |
|         0x320, 0x013}, {
 | |
|         0x321, 0x213}, {
 | |
|         0x322, 0x113}, {
 | |
|         0x323, 0x313}, {
 | |
|         0x324, 0x093}, {
 | |
|         0x325, 0x293}, {
 | |
|         0x326, 0x193}, {
 | |
|         0x328, 0x053}, {
 | |
|         0x329, 0x253}, {
 | |
|         0x32a, 0x153}, {
 | |
|         0x32c, 0x0d3}, {
 | |
|         0x32d, 0x2d3}, {
 | |
|         0x32e, 0x1d3}, {
 | |
|         0x330, 0x033}, {
 | |
|         0x331, 0x233}, {
 | |
|         0x332, 0x133}, {
 | |
|         0x334, 0x0b3}, {
 | |
|         0x335, 0x2b3}, {
 | |
|         0x336, 0x1b3}, {
 | |
|         0x338, 0x073}, {
 | |
|         0x339, 0x273}, {
 | |
|         0x33a, 0x173}, {
 | |
|         0x33c, 0x0f3}, {
 | |
|         0x33d, 0x2f3}, {
 | |
|         0x33e, 0x1f3}, {
 | |
|         0x340, 0x00b}, {
 | |
|         0x341, 0x20b}, {
 | |
|         0x342, 0x10b}, {
 | |
|         0x343, 0x30b}, {
 | |
|         0x344, 0x08b}, {
 | |
|         0x345, 0x28b}, {
 | |
|         0x346, 0x18b}, {
 | |
|         0x348, 0x04b}, {
 | |
|         0x349, 0x24b}, {
 | |
|         0x34a, 0x14b}, {
 | |
|         0x34c, 0x0cb}, {
 | |
|         0x34d, 0x2cb}, {
 | |
|         0x34e, 0x1cb}, {
 | |
|         0x350, 0x02b}, {
 | |
|         0x351, 0x22b}, {
 | |
|         0x352, 0x12b}, {
 | |
|         0x353, 0x32b}, {
 | |
|         0x354, 0x0ab}, {
 | |
|         0x355, 0x2ab}, {
 | |
|         0x356, 0x1ab}, {
 | |
|         0x358, 0x06b}, {
 | |
|         0x359, 0x26b}, {
 | |
|         0x35a, 0x16b}, {
 | |
|         0x35c, 0x0eb}, {
 | |
|         0x35d, 0x2eb}, {
 | |
|         0x35e, 0x1eb}, {
 | |
|         0x360, 0x01b}, {
 | |
|         0x361, 0x21b}, {
 | |
|         0x362, 0x11b}, {
 | |
|         0x363, 0x31b}, {
 | |
|         0x364, 0x09b}, {
 | |
|         0x365, 0x29b}, {
 | |
|         0x366, 0x19b}, {
 | |
|         0x368, 0x05b}, {
 | |
|         0x369, 0x25b}, {
 | |
|         0x36a, 0x15b}, {
 | |
|         0x36b, 0x35b}, {
 | |
|         0x36c, 0x0db}, {
 | |
|         0x36d, 0x2db}, {
 | |
|         0x36e, 0x1db}, {
 | |
|         0x370, 0x03b}, {
 | |
|         0x371, 0x23b}, {
 | |
|         0x372, 0x13b}, {
 | |
|         0x373, 0x33b}, {
 | |
|         0x374, 0x0bb}, {
 | |
|         0x375, 0x2bb}, {
 | |
|         0x376, 0x1bb}, {
 | |
|         0x378, 0x07b}, {
 | |
|         0x379, 0x27b}, {
 | |
|         0x37a, 0x17b}, {
 | |
|         0x37c, 0x0fb}, {
 | |
|         0x37d, 0x2fb}, {
 | |
|         0x37e, 0x1fb}, {
 | |
|         0x380, 0x007}, {
 | |
|         0x381, 0x207}, {
 | |
|         0x382, 0x107}, {
 | |
|         0x383, 0x307}, {
 | |
|         0x384, 0x087}, {
 | |
|         0x385, 0x287}, {
 | |
|         0x386, 0x187}, {
 | |
|         0x388, 0x047}, {
 | |
|         0x389, 0x247}, {
 | |
|         0x38a, 0x147}, {
 | |
|         0x38b, 0x347}, {
 | |
|         0x38c, 0x0c7}, {
 | |
|         0x38d, 0x2c7}, {
 | |
|         0x38e, 0x1c7}, {
 | |
|         0x390, 0x027}, {
 | |
|         0x391, 0x227}, {
 | |
|         0x392, 0x127}, {
 | |
|         0x393, 0x327}, {
 | |
|         0x394, 0x0a7}, {
 | |
|         0x395, 0x2a7}, {
 | |
|         0x396, 0x1a7}, {
 | |
|         0x398, 0x067}, {
 | |
|         0x399, 0x267}, {
 | |
|         0x39a, 0x167}, {
 | |
|         0x39b, 0x367}, {
 | |
|         0x39c, 0x0e7}, {
 | |
|         0x39d, 0x2e7}, {
 | |
|         0x39e, 0x1e7}, {
 | |
|         0x3a0, 0x017}, {
 | |
|         0x3a1, 0x217}, {
 | |
|         0x3a2, 0x117}, {
 | |
|         0x3a3, 0x317}, {
 | |
|         0x3a4, 0x097}, {
 | |
|         0x3a5, 0x297}, {
 | |
|         0x3a6, 0x197}, {
 | |
|         0x3a7, 0x397}, {
 | |
|         0x3a8, 0x057}, {
 | |
|         0x3a9, 0x257}, {
 | |
|         0x3aa, 0x157}, {
 | |
|         0x3ab, 0x357}, {
 | |
|         0x3ac, 0x0d7}, {
 | |
|         0x3ad, 0x2d7}, {
 | |
|         0x3ae, 0x1d7}, {
 | |
|         0x3b0, 0x037}, {
 | |
|         0x3b1, 0x237}, {
 | |
|         0x3b2, 0x137}, {
 | |
|         0x3b3, 0x337}, {
 | |
|         0x3b4, 0x0b7}, {
 | |
|         0x3b5, 0x2b7}, {
 | |
|         0x3b6, 0x1b7}, {
 | |
|         0x3b8, 0x077}, {
 | |
|         0x3b9, 0x277}, {
 | |
|         0x3ba, 0x177}, {
 | |
|         0x3bb, 0x377}, {
 | |
|         0x3bc, 0x0f7}, {
 | |
|         0x3bd, 0x2f7}, {
 | |
|         0x3be, 0x1f7}, {
 | |
|         0x3c0, 0x00f}, {
 | |
|         0x3c1, 0x20f}, {
 | |
|         0x3c2, 0x10f}, {
 | |
|         0x3c3, 0x30f}, {
 | |
|         0x3c4, 0x08f}, {
 | |
|         0x3c5, 0x28f}, {
 | |
|         0x3c6, 0x18f}, {
 | |
|         0x3c7, 0x38f}, {
 | |
|         0x3c8, 0x04f}, {
 | |
|         0x3c9, 0x24f}, {
 | |
|         0x3ca, 0x14f}, {
 | |
|         0x3cb, 0x34f}, {
 | |
|         0x3cc, 0x0cf}, {
 | |
|         0x3cd, 0x2cf}, {
 | |
|         0x3ce, 0x1cf}, {
 | |
|         0x3d0, 0x02f}, {
 | |
|         0x3d1, 0x22f}, {
 | |
|         0x3d2, 0x12f}, {
 | |
|         0x3d3, 0x32f}, {
 | |
|         0x3d4, 0x0af}, {
 | |
|         0x3d5, 0x2af}, {
 | |
|         0x3d6, 0x1af}, {
 | |
|         0x3d7, 0x3af}, {
 | |
|         0x3d8, 0x06f}, {
 | |
|         0x3d9, 0x26f}, {
 | |
|         0x3da, 0x16f}, {
 | |
|         0x3db, 0x36f}, {
 | |
|         0x3dc, 0x0ef}, {
 | |
|         0x3dd, 0x2ef}, {
 | |
|         0x3de, 0x1ef}, {
 | |
|         0x3e0, 0x01f}, {
 | |
|         0x3e1, 0x21f}, {
 | |
|         0x3e2, 0x11f}, {
 | |
|         0x3e3, 0x31f}, {
 | |
|         0x3e4, 0x09f}, {
 | |
|         0x3e5, 0x29f}, {
 | |
|         0x3e6, 0x19f}, {
 | |
|         0x3e7, 0x39f}, {
 | |
|         0x3e8, 0x05f}, {
 | |
|         0x3e9, 0x25f}, {
 | |
|         0x3ea, 0x15f}, {
 | |
|         0x3eb, 0x35f}, {
 | |
|         0x3ec, 0x0df}, {
 | |
|         0x3ed, 0x2df}, {
 | |
|         0x3ee, 0x1df}, {
 | |
|         0x3ef, 0x3df}, {
 | |
|         0x3f0, 0x03f}, {
 | |
|         0x3f1, 0x23f}, {
 | |
|         0x3f2, 0x13f}, {
 | |
|         0x3f3, 0x33f}, {
 | |
|         0x3f4, 0x0bf}, {
 | |
|         0x3f5, 0x2bf}, {
 | |
|         0x3f6, 0x1bf}, {
 | |
|         0x3f7, 0x3bf}, {
 | |
|         0x3f8, 0x07f}, {
 | |
|         0x3f9, 0x27f}, {
 | |
|         0x3fa, 0x17f}, {
 | |
|         0x3fb, 0x37f}, {
 | |
|         0x3fc, 0x0ff}, {
 | |
|         0x3fd, 0x2ff}, {
 | |
|         0x3fe, 0x1ff}
 | |
|     };
 | |
| 
 | |
| 
 | |
|     {
 | |
|         int i;
 | |
|         for (i = 0; i < sizeof k1k2tab / sizeof k1k2tab[0]; ++i) {
 | |
|             k1 = k1k2tab[i].k1;
 | |
|             k2 = k1k2tab[i].k2;
 | |
|             a = fz[k1];
 | |
|             fz[k1] = fz[k2];
 | |
|             fz[k2] = a;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     for (fi = fz, fn = fz + 1024; fi < fn; fi += 4) {
 | |
|         FLOAT f0, f1, f2, f3;
 | |
|         f1 = fi[0] - fi[1];
 | |
|         f0 = fi[0] + fi[1];
 | |
|         f3 = fi[2] - fi[3];
 | |
|         f2 = fi[2] + fi[3];
 | |
|         fi[2] = (f0 - f2);
 | |
|         fi[0] = (f0 + f2);
 | |
|         fi[3] = (f1 - f3);
 | |
|         fi[1] = (f1 + f3);
 | |
|     }
 | |
| 
 | |
|     k = 0;
 | |
|     do {
 | |
|         FLOAT s1, c1;
 | |
|         k += 2;
 | |
|         k1 = 1 << k;
 | |
|         k2 = k1 << 1;
 | |
|         k4 = k2 << 1;
 | |
|         k3 = k2 + k1;
 | |
|         kx = k1 >> 1;
 | |
|         fi = fz;
 | |
|         gi = fi + kx;
 | |
|         fn = fz + 1024;
 | |
|         do {
 | |
|             FLOAT g0, f0, f1, g1, f2, g2, f3, g3;
 | |
|             f1 = fi[0] - fi[k1];
 | |
|             f0 = fi[0] + fi[k1];
 | |
|             f3 = fi[k2] - fi[k3];
 | |
|             f2 = fi[k2] + fi[k3];
 | |
|             fi[k2] = f0 - f2;
 | |
|             fi[0] = f0 + f2;
 | |
|             fi[k3] = f1 - f3;
 | |
|             fi[k1] = f1 + f3;
 | |
|             g1 = gi[0] - gi[k1];
 | |
|             g0 = gi[0] + gi[k1];
 | |
|             g3 = SQRT2 * gi[k3];
 | |
|             g2 = SQRT2 * gi[k2];
 | |
|             gi[k2] = g0 - g2;
 | |
|             gi[0] = g0 + g2;
 | |
|             gi[k3] = g1 - g3;
 | |
|             gi[k1] = g1 + g3;
 | |
|             gi += k4;
 | |
|             fi += k4;
 | |
|         }
 | |
|         while (fi < fn);
 | |
| 
 | |
|         t_c = costab[k];
 | |
|         t_s = sintab[k];
 | |
|         c1 = 1;
 | |
|         s1 = 0;
 | |
|         for (i = 1; i < kx; i++) {
 | |
|             FLOAT c2, s2;
 | |
|             FLOAT t = c1;
 | |
|             c1 = t * t_c - s1 * t_s;
 | |
|             s1 = t * t_s + s1 * t_c;
 | |
|             c2 = c1 * c1 - s1 * s1;
 | |
|             s2 = 2 * (c1 * s1);
 | |
|             fn = fz + 1024;
 | |
|             fi = fz + i;
 | |
|             gi = fz + k1 - i;
 | |
|             do {
 | |
|                 FLOAT a, b, g0, f0, f1, g1, f2, g2, f3, g3;
 | |
|                 b = s2 * fi[k1] - c2 * gi[k1];
 | |
|                 a = c2 * fi[k1] + s2 * gi[k1];
 | |
|                 f1 = fi[0] - a;
 | |
|                 f0 = fi[0] + a;
 | |
|                 g1 = gi[0] - b;
 | |
|                 g0 = gi[0] + b;
 | |
|                 b = s2 * fi[k3] - c2 * gi[k3];
 | |
|                 a = c2 * fi[k3] + s2 * gi[k3];
 | |
|                 f3 = fi[k2] - a;
 | |
|                 f2 = fi[k2] + a;
 | |
|                 g3 = gi[k2] - b;
 | |
|                 g2 = gi[k2] + b;
 | |
|                 b = s1 * f2 - c1 * g3;
 | |
|                 a = c1 * f2 + s1 * g3;
 | |
|                 fi[k2] = f0 - a;
 | |
|                 fi[0] = f0 + a;
 | |
|                 gi[k3] = g1 - b;
 | |
|                 gi[k1] = g1 + b;
 | |
|                 b = c1 * g2 - s1 * f3;
 | |
|                 a = s1 * g2 + c1 * f3;
 | |
|                 gi[k2] = g0 - a;
 | |
|                 gi[0] = g0 + a;
 | |
|                 fi[k3] = f1 - b;
 | |
|                 fi[k1] = f1 + b;
 | |
|                 gi += k4;
 | |
|                 fi += k4;
 | |
|             }
 | |
|             while (fi < fn);
 | |
|         }
 | |
|     }
 | |
|     while (k4 < 1024);
 | |
| }
 | |
| 
 | |
| #ifdef NEWATAN
 | |
| #define ATANSIZE 6000
 | |
| #define ATANSCALE 100.0
 | |
| /* Create a table of ATAN2 values.
 | |
|    Valid for ratios of (y/x) from 0 to ATANSIZE/ATANSCALE (60) 
 | |
|    Largest absolute error in angle: 0.0167 radians i.e. ATANSCALE/ATANSIZE 
 | |
|    Depending on how you want to trade off speed/accuracy and mem usage, twiddle the defines
 | |
|    MFC March 2003 */
 | |
| static FLOAT atan_t[ATANSIZE];
 | |
| 
 | |
| static inline FLOAT atan_table(FLOAT y, FLOAT x)
 | |
| {
 | |
|     int index;
 | |
| 
 | |
|     index = (int) (ATANSCALE * fabs(y / x));
 | |
|     if (index >= ATANSIZE)
 | |
|         index = ATANSIZE - 1;
 | |
| 
 | |
|     /* Have to work out the correct quadrant as well */
 | |
|     if (y > 0 && x < 0)
 | |
|         return (PI - atan_t[index]);
 | |
| 
 | |
|     if (y < 0 && x > 0)
 | |
|         return (-atan_t[index]);
 | |
| 
 | |
|     if (y < 0 && x < 0)
 | |
|         return (atan_t[index] - PI);
 | |
| 
 | |
|     return (atan_t[index]);
 | |
| }
 | |
| 
 | |
| static void atan_table_init(void)
 | |
| {
 | |
|     int i;
 | |
|     for (i = 0; i < ATANSIZE; i++)
 | |
|         atan_t[i] = atan((FLOAT) i / ATANSCALE);
 | |
| }
 | |
| 
 | |
| #endif                          // NEWATAN
 | |
| 
 | |
| /* For variations on psycho model 2:
 | |
|    N always equals 1024
 | |
|    BUT in the returned values, no energy/phi is used at or above an index of 513 */
 | |
| void psycho_2_fft(FLOAT * x_real, FLOAT * energy, FLOAT * phi)
 | |
| /* got rid of size "N" argument as it is always 1024 for layerII */
 | |
| {
 | |
|     FLOAT imag, real;
 | |
|     int i, j;
 | |
| #ifdef NEWATAN
 | |
|     static int init = 0;
 | |
| 
 | |
|     if (!init) {
 | |
|         atan_table_init();
 | |
|         init++;
 | |
|     }
 | |
| #endif
 | |
| 
 | |
| 
 | |
|     fht(x_real);
 | |
| 
 | |
| 
 | |
|     energy[0] = x_real[0] * x_real[0];
 | |
| 
 | |
|     for (i = 1, j = 1023; i < 512; i++, j--) {
 | |
|         imag = x_real[i];
 | |
|         real = x_real[j];
 | |
|         /* MFC FIXME Mar03 Why is this divided by 2.0? if a and b are the real and imaginary
 | |
|            components then r = sqrt(a^2 + b^2), but, back in the psycho2 model, they calculate
 | |
|            r=sqrt(energy), which, if you look at the original equation below is different */
 | |
|         energy[i] = (imag * imag + real * real) / 2.0;
 | |
|         if (energy[i] < 0.0005) {
 | |
|             energy[i] = 0.0005;
 | |
|             phi[i] = 0;
 | |
|         } else
 | |
| #ifdef NEWATAN
 | |
|         {
 | |
|             phi[i] = atan_table(-imag, real) + PI / 4;
 | |
|         }
 | |
| #else
 | |
|         {
 | |
|             phi[i] = atan2(-(FLOAT) imag, (FLOAT) real) + PI / 4;
 | |
|         }
 | |
| #endif
 | |
|     }
 | |
|     energy[512] = x_real[512] * x_real[512];
 | |
|     phi[512] = atan2(0.0, (FLOAT) x_real[512]);
 | |
| }
 | |
| 
 | |
| 
 | |
| void psycho_1_fft(FLOAT * x_real, FLOAT * energy, int N)
 | |
| {
 | |
|     FLOAT a, b;
 | |
|     int i, j;
 | |
| 
 | |
|     fht(x_real);
 | |
| 
 | |
|     energy[0] = x_real[0] * x_real[0];
 | |
| 
 | |
|     for (i = 1, j = N - 1; i < N / 2; i++, j--) {
 | |
|         a = x_real[i];
 | |
|         b = x_real[j];
 | |
|         energy[i] = (a * a + b * b) / 2.0;
 | |
|     }
 | |
|     energy[N / 2] = x_real[N / 2] * x_real[N / 2];
 | |
| }
 | |
| 
 | |
| 
 | |
| // vim:ts=4:sw=4:nowrap: 
 |