Skip to content

Commit

Permalink
import old-style scfft library
Browse files Browse the repository at this point in the history
Signed-off-by: Tim Blechmann <[email protected]>

git-svn-id: https://sc3-plugins.svn.sourceforge.net/svnroot/sc3-plugins@455 a81c72af-a122-0410-9629-e4559562533e
  • Loading branch information
Tim Blechmann committed Dec 3, 2010
1 parent 2299db0 commit 4806cc2
Show file tree
Hide file tree
Showing 9 changed files with 721 additions and 6 deletions.
151 changes: 151 additions & 0 deletions scfft_old/SCComplex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
SuperCollider real time audio synthesis system
Copyright (c) 2002 James McCartney. All rights reserved.
http://www.audiosynth.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/


#include "SCComplex.h"
#include "SC_Types.h"
#include "SC_Constants.h"
#include "SC_InterfaceTable.h"
#include <math.h>

////////////////////////////////////////////////////////////////////////////////

const int32 kPolarLUTSize = 2049;
const int32 kPolarLUTSize2 = kPolarLUTSize >> 1;
float gMagLUT[kPolarLUTSize];
float gPhaseLUT[kPolarLUTSize];

static float gSinePhaseScale;
static int gSineSize;
static float *gSine;
static int gSineMask;

void init_SCComplex(InterfaceTable *ft);
void init_SCComplex(InterfaceTable *ft)
{
gSineSize = ft->mSineSize;
gSine = ft->mSine;
gSinePhaseScale = gSineSize / twopi_f;
gSineMask = gSineSize - 1;

double rPolarLUTSize2 = 1. / kPolarLUTSize2;
for (int i=0; i < kPolarLUTSize; ++i) {
double slope = (i - kPolarLUTSize2) * rPolarLUTSize2;
double angle = atan(slope);
gPhaseLUT[i] = (float)angle;
gMagLUT[i] = 1.f / (float)cos(angle);
}
}

SCPolar SCComplex::ToPolar()
{
return SCPolar(hypot(imag, real), atan2(imag, real));
}

SCComplex SCPolar::ToComplex()
{
return SCComplex(mag * cos(phase), mag * sin(phase));
}

/*
float fhypotx(float real, float imag);
float fhypotx(float real, float imag)
{
int32 index;
float absreal = fabs(real);
float absimag = fabs(imag);
float slope;
if (absreal > absimag) {
slope = imag/real;
index = kPolarLUTSize2 + kPolarLUTSize2 * slope;
return gMagLUT[index] * absreal;
} else {
slope = real/imag;
index = kPolarLUTSize2 + kPolarLUTSize2 * slope;
return gMagLUT[index] * absimag;
}
}
*/

SCPolar SCComplex::ToPolarApx()
{
int32 index;
float absreal = fabs(real);
float absimag = fabs(imag);
float slope;
if (absreal > absimag) {
slope = imag/real;
index = kPolarLUTSize2 + (int32)(kPolarLUTSize2 * slope);
if (real > 0) {
return SCPolar(gMagLUT[index] * absreal, gPhaseLUT[index]);
} else {
return SCPolar(gMagLUT[index] * absreal, pi_f + gPhaseLUT[index]);
}
} else if(absimag==0.f) { // because of the above test, this means real is also zero
return SCPolar(0.f, 0.f);
} else {
slope = real/imag;
index = kPolarLUTSize2 + (int32)(kPolarLUTSize2 * slope);
if (imag > 0) {
return SCPolar(gMagLUT[index] * absimag, pi2_f - gPhaseLUT[index]);
} else {
return SCPolar(gMagLUT[index] * absimag, pi32_f - gPhaseLUT[index]);
}
}
}

void SCComplex::ToPolarInPlace()
{
SCPolar polar = ToPolar();
real = polar.mag;
imag = polar.phase;
}

void SCPolar::ToComplexInPlace()
{
SCComplex complx = ToComplex();
mag = complx.real;
phase = complx.imag;
}

SCComplex SCPolar::ToComplexApx()
{
uint32 sinindex = (int32)((double)gSinePhaseScale * phase) & gSineMask;
uint32 cosindex = (sinindex + (gSineSize>>2)) & gSineMask;
return SCComplex(mag * gSine[cosindex], mag * gSine[sinindex]);
}

void SCComplex::ToPolarApxInPlace()
{
SCPolar polar = ToPolarApx();
real = polar.mag;
imag = polar.phase;
}

void SCPolar::ToComplexApxInPlace()
{
SCComplex complx = ToComplexApx();
mag = complx.real;
phase = complx.imag;
}

////////////////////////////////////////////////////////////////////////////////

128 changes: 128 additions & 0 deletions scfft_old/SCComplex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
SuperCollider real time audio synthesis system
Copyright (c) 2002 James McCartney. All rights reserved.
http://www.audiosynth.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/


#ifndef _SCComplex_
#define _SCComplex_

////////////////////////////////////////////////////////////////////////////////

struct SCPolar;

struct SCComplex
{
SCComplex(float r, float i) : real(r), imag(i) {}
void Set(float r, float i) { real = r; imag = i; }

SCComplex& operator=(SCComplex b) { real = b.real; imag = b.imag; return *this; }
SCComplex& operator=(float b) { real = b; imag = 0.; return *this; }

SCPolar ToPolar();
SCPolar ToPolarApx();

void ToPolarInPlace();
void ToPolarApxInPlace();

float real, imag;
};

struct SCPolar
{
SCPolar(float m, float p) : mag(m), phase(p) {}
void Set(float m, float p) { mag = m; phase = p; }

SCPolar& operator=(SCPolar b) { mag = b.mag; phase = b.phase; return *this; }
SCPolar& operator=(float b) { mag = b; phase = 0.; return *this; }

SCComplex ToComplex();
SCComplex ToComplexApx();

void ToComplexInPlace();
void ToComplexApxInPlace();

float mag, phase;
};

void ToComplex(SCPolar in, SCComplex& out);

inline SCComplex operator+(SCComplex a, SCComplex b) { return SCComplex(a.real + b.real, a.imag + b.imag); }
inline SCComplex operator+(SCComplex a, float b) { return SCComplex(a.real + b, a.imag); }
inline SCComplex operator+(float a, SCComplex b) { return SCComplex(a + b.real, b.imag); }

inline SCComplex& operator+=(SCComplex& a, const SCComplex& b) { a.real += b.real, a.imag += b.imag; return a; }
inline SCComplex& operator+=(SCComplex& a, float b) { a.real += b; return a; }

inline SCComplex operator-(SCComplex a, SCComplex b) { return SCComplex(a.real - b.real, a.imag - b.imag); }
inline SCComplex operator-(SCComplex a, float b) { return SCComplex(a.real - b, a.imag); }
inline SCComplex operator-(float a, SCComplex b) { return SCComplex(a - b.real, b.imag); }

inline SCComplex operator-=(SCComplex a, SCComplex b) { a.real -= b.real, a.imag -= b.imag; return a; }
inline SCComplex operator-=(SCComplex a, float b) { a.real -= b; return a; }

inline SCComplex operator*(SCComplex a, SCComplex b)
{
return SCComplex(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real);
}

inline SCComplex operator*(SCComplex a, float b)
{
return SCComplex(a.real * b, a.imag * b);
}

inline SCComplex operator*(float a, SCComplex b)
{
return SCComplex(b.real * a, b.imag * a);
}

inline SCComplex operator*=(SCComplex a, SCComplex b)
{
a.Set(
a.real * b.real - a.imag * b.imag,
a.real * b.imag + a.imag * b.real
);
return a;
}

inline SCComplex operator*=(SCComplex a, float b)
{
a.real *= b;
a.imag *= b;
return a;
}


inline SCPolar operator*(SCPolar a, float b)
{
return SCPolar(a.mag * b, a.phase);
}

inline SCPolar operator*(float a, SCPolar b)
{
return SCPolar(a * b.mag, b.phase);
}

inline SCPolar operator*=(SCPolar a, float b)
{
a.mag *= b;
return a;
}


#endif
Loading

0 comments on commit 4806cc2

Please sign in to comment.