2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SC_Complex.h"
23 #include "SC_Constants.h"
27 ////////////////////////////////////////////////////////////////////////////////
29 const int32 kPolarLUTSize
= 2049;
30 const int32 kPolarLUTSize2
= kPolarLUTSize
>> 1;
31 const double kSinePhaseScale
= (double)kSineSize
/ twopi
;
32 float gMagLUT
[kPolarLUTSize
];
33 float gPhaseLUT
[kPolarLUTSize
];
38 double rPolarLUTSize2
= 1. / kPolarLUTSize2
;
39 for (int i
=0; i
< kPolarLUTSize
; ++i
) {
40 double slope
= (i
- kPolarLUTSize2
) * rPolarLUTSize2
;
41 double angle
= atan(slope
);
42 gPhaseLUT
[i
] = (float)angle
;
43 gMagLUT
[i
] = 1.f
/ (float)cos(angle
);
47 Polar
Complex::ToPolar()
49 return Polar(hypot(imag
, real
), atan2(imag
, real
));
52 Complex
Polar::ToComplex()
54 return Complex(mag
* cos(phase
), mag
* sin(phase
));
58 float fhypotx(float real, float imag);
59 float fhypotx(float real, float imag)
63 float absreal = fabs(real);
64 float absimag = fabs(imag);
66 if (absreal > absimag) {
68 index = kPolarLUTSize2 + kPolarLUTSize2 * slope;
69 return gMagLUT[index] * absreal;
72 index = kPolarLUTSize2 + kPolarLUTSize2 * slope;
73 return gMagLUT[index] * absimag;
79 * Converts cartesian to polar representation, using lookup tables.
80 * Note: in this implementation the phase values returned lie in the range [-pi/4, 7pi/4]
81 * rather than the more conventional [0, 2pi] or [-pi, pi].
83 Polar
Complex::ToPolarApx()
86 float absreal
= fabs(real
);
87 float absimag
= fabs(imag
);
88 float mag
, phase
, slope
;
89 if (absreal
> absimag
) {
91 index
= (int32
)(kPolarLUTSize2
+ kPolarLUTSize2
* slope
);
92 mag
= gMagLUT
[index
] * absreal
;
93 phase
= gPhaseLUT
[index
];
95 return Polar(mag
, phase
);
97 return Polar(mag
, (float)(pi
+ phase
));
101 index
= (int32
)(kPolarLUTSize2
+ kPolarLUTSize2
* slope
);
102 mag
= gMagLUT
[index
] * absimag
;
103 phase
= gPhaseLUT
[index
];
105 return Polar(mag
, (float)(pi2
- phase
));
107 return Polar(mag
, (float)(pi32
- phase
));
112 void Complex::ToPolarInPlace()
114 Polar polar
= ToPolar();
119 void Polar::ToComplexInPlace()
121 Complex complx
= ToComplex();
126 Complex
Polar::ToComplexApx()
128 uint32 sinindex
= (int32
)(kSinePhaseScale
* phase
) & kSineMask
;
129 uint32 cosindex
= (sinindex
+ (kSineSize
>>2)) & kSineMask
;
130 return Complex(mag
* gSine
[cosindex
], mag
* gSine
[sinindex
]);
133 void Complex::ToPolarApxInPlace()
135 Polar polar
= ToPolarApx();
140 void Polar::ToComplexApxInPlace()
142 Complex complx
= ToComplexApx();
147 ////////////////////////////////////////////////////////////////////////////////