Update of /cvsroot/pure-data/externals/sc4pd/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13248/source
Modified Files: main.cpp support.cpp support.hpp Added Files: Convolution.cpp fftlib.c fftlib.h scmul.cpp Removed Files: sc*.cpp Log Message: ...
Index: support.hpp =================================================================== RCS file: /cvsroot/pure-data/externals/sc4pd/source/support.hpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** support.hpp 9 Sep 2004 08:45:18 -0000 1.9 --- support.hpp 11 Sep 2004 08:10:45 -0000 1.10 *************** *** 116,119 **** --- 116,124 ----
+ /* from Convolution.cpp */ + void init_ffts(); + float* create_fftwindow(int log2n); + float* create_cosTable(int log2n); + void DoWindowing(int log2n, float * fftbuf, int bufsize);
#endif
--- NEW FILE: scmul.cpp --- /* sc4pd sc*~
Copyright (c) 2004 Tim Blechmann.
This code is derived from: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Based on: PureData by Miller Puckette and others. http://www.crca.ucsd.edu/~msp/software.html FLEXT by Thomas Grill http://www.parasitaere-kapazitaeten.net/ext SuperCollider by James McCartney http://www.audiosynth.com
Coded while listening to: Phil Minton & Veryan Weston: Ways
*/
#include "sc4pd.hpp"
/* ------------------------ sc*~ -------------------------------*/
class scmul_ar: public sc4pd_dsp { FLEXT_HEADER(scmul_ar,sc4pd_dsp);
public: scmul_ar(int argc, t_atom *argv);
protected: virtual void m_signal(int n, t_sample *const *in, t_sample *const *out);
void m_set(float f) { m_nextfactor = f; changed = true; }
float m_nextfactor, m_factor; bool changed;
private: FLEXT_CALLBACK_1(m_set,float); };
FLEXT_LIB_DSP_V("sc*~",scmul_ar);
scmul_ar::scmul_ar(int argc, t_atom *argv) { FLEXT_ADDMETHOD(1,m_set);
//parse arguments AtomList Args(argc,argv);
m_factor = sc_getfloatarg(Args,0);
AddInSignal("signal"); AddInFloat("scalar"); AddOutSignal();
changed = false; }
void scmul_ar::m_signal(int n, t_sample *const *in, t_sample *const *out) { t_sample *nin = *in; t_sample *nout = *out;
if (changed) { float xb = m_nextfactor; float slope = CALCSLOPE(xb, m_factor); for (int i = 0; i!=n; ++i) { ZXP(nout) = ZXP(nin) * xb; xb += slope; } m_factor = xb; changed = false; } else { float xb = m_factor;
for (int i = 0; i!=n; ++i) { ZXP(nout) = ZXP(nin) * xb; } } }
Index: main.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/sc4pd/source/main.cpp,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** main.cpp 9 Sep 2004 08:45:18 -0000 1.27 --- main.cpp 11 Sep 2004 08:10:45 -0000 1.28 *************** *** 1,2 **** --- 1,3 ---- + /* sc4pd library initialization *************** *** 69,73 **** " LPZ1(~), HPZ1(~), LPZ2(~), HPZ2(~), BPZ2(~), BRZ2(~), " "LFDNoise0~,\n" ! " LFDNoise1~, LFDNoise2~, sc+~, sc-~, sc*~, sc/~\n" );
--- 70,75 ---- " LPZ1(~), HPZ1(~), LPZ2(~), HPZ2(~), BPZ2(~), BRZ2(~), " "LFDNoise0~,\n" ! " LFDNoise1~, LFDNoise2~, sc+~, sc-~, sc*~, sc/~, " ! "Convolution~\n" );
*************** *** 297,300 **** --- 299,307 ----
FLEXT_DSP_SETUP(scdiv_ar); + + FLEXT_DSP_SETUP(Convolution_ar); + + //init ffts + init_ffts(); }
Index: support.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/sc4pd/source/support.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** support.cpp 9 Sep 2004 08:45:18 -0000 1.5 --- support.cpp 11 Sep 2004 08:10:45 -0000 1.6 *************** *** 109,110 **** --- 109,184 ---- return (int32)tsec ^ (int32)tusec ^ count--; } + + /* from Convolution.cpp */ + extern "C" + { + float *cosTable[32]; + float *fftWindow[32]; + } + + + float* create_cosTable(int log2n) + { + int size = 1 << log2n; + int size2 = size / 4 + 1; + float *win = (float*)malloc(size2 * sizeof(float)); + double winc = twopi / size; + for (int i=0; i<size2; ++i) { + double w = i * winc; + win[i] = cos(w); + } + return win; + } + + float* create_fftwindow(int log2n) + { + int size = 1 << log2n; + float *win = (float*)malloc(size * sizeof(float)); + //double winc = twopi / size; + double winc = pi / size; + for (int i=0; i<size; ++i) { + double w = i * winc; + //win[i] = 0.5 - 0.5 * cos(w); + win[i] = sin(w); + } + return win; + } + + void init_ffts() + { + #if __VEC__ + + for (int i=0; i<32; ++i) { + fftsetup[i] = 0; + } + for (int i=0; i<15; ++i) { + fftsetup[i] = create_fftsetup(i, kFFTRadix2); + } + #else + for (int i=0; i<32; ++i) { + cosTable[i] = 0; + fftWindow[i] = 0; + } + for (int i=3; i<15; ++i) { + cosTable[i] = create_cosTable(i); + fftWindow[i] = create_fftwindow(i); + } + #endif + } + + void DoWindowing(int log2n, float * fftbuf, int bufsize) + { + float *win = fftWindow[log2n]; + + //printf("fail? %i %d /n", log2n, win); + + if (!win) return; + float *in = fftbuf - 1; + win--; + + for (int i=0; i<bufsize; ++i) { + *++in *= *++win; + } + } + + #include "fftlib.c"
--- NEW FILE: Convolution.cpp --- /* sc4pd Convolution~
Copyright (c) 2004 Tim Blechmann.
This code is derived from: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Based on: PureData by Miller Puckette and others. http://www.crca.ucsd.edu/~msp/software.html FLEXT by Thomas Grill http://www.parasitaere-kapazitaeten.net/ext SuperCollider by James McCartney http://www.audiosynth.com
Coded while listening to: Ambarchi/Muller/Voice Crack: Oystered
*/
#include "sc4pd.hpp" #include "fftlib.h"
/* ------------------------ Convolution~ -------------------------------*/
class Convolution_ar: public sc4pd_dsp { FLEXT_HEADER(Convolution_ar,sc4pd_dsp);
public: Convolution_ar(int argc, t_atom *argv); ~Convolution_ar();
protected: virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out);
private: int m_pos, m_insize, m_fftsize,m_mask; int m_log2n;
float *m_inbuf1,*m_inbuf2, *m_fftbuf1, *m_fftbuf2, *m_outbuf,*m_overlapbuf;
};
FLEXT_LIB_DSP_V("Convolution~",Convolution_ar);
Convolution_ar::Convolution_ar(int argc, t_atom *argv) {
//parse arguments AtomList Args(argc,argv);
m_insize = sc_getfloatarg(Args,0);
AddInSignal("signal"); AddInSignal("kernel"); AddOutSignal();
//require size N+M-1 to be a power of two
m_fftsize=2*(m_insize);
//just use memory for the input buffers and fft buffers int insize = m_insize * sizeof(float); int fftsize = m_fftsize * sizeof(float);
m_inbuf1 = new float[m_insize]; m_inbuf2 = new float[m_insize];
m_fftbuf1 = new float[m_fftsize]; m_fftbuf2 = new float[m_fftsize];
m_outbuf = new float[m_fftsize]; m_overlapbuf = new float[m_insize];
memset(m_outbuf, 0, fftsize); memset(m_overlapbuf, 0, insize);
m_log2n = LOG2CEIL(m_fftsize);
//test for full input buffer m_mask = m_insize; m_pos = 0; }
Convolution_ar::~Convolution_ar() { delete m_inbuf1; delete m_inbuf2;
delete m_fftbuf1; delete m_fftbuf2;
delete m_outbuf; delete m_overlapbuf; }
void Convolution_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) {
}
extern float* cosTable[32];
void Convolution_ar::m_signal(int n, t_sample *const *in, t_sample *const *out) { float *in1 = in[0]; float *in2 = in[1];
float *out1 = m_inbuf1 + m_pos; float *out2 = m_inbuf2 + m_pos; int numSamples = 2*n; //??? mWorld->mFullRate.mBufLength;
// copy input CopySamples(out1, in1, numSamples); CopySamples(out2, in2, numSamples); m_pos += numSamples;
if (m_pos & m_insize) {
//have collected enough samples to transform next frame m_pos = 0; //reset collection counter // copy to fftbuf
uint32 insize=m_insize * sizeof(float); memcpy(m_fftbuf1, m_inbuf1, insize); memcpy(m_fftbuf2, m_inbuf2, insize); //zero pad second part of buffer to allow for convolution memset(m_fftbuf1+m_insize, 0, insize); memset(m_fftbuf2+m_insize, 0, insize);
int log2n = m_log2n;
// do windowing DoWindowing(log2n, m_fftbuf1, m_fftsize); DoWindowing(log2n, m_fftbuf2, m_fftsize); // do fft /* #if __VEC__ ctoz(m_fftbuf1, 2, outbuf1, 1, 1L<<log2n); ctoz(m_fftbuf2, 2, outbuf2, 1, 1L<<log2n); #else */
//in place transform for now rffts(m_fftbuf1, log2n, 1, cosTable[log2n]); rffts(m_fftbuf2, log2n, 1, cosTable[log2n]); //#endif
//complex multiply time int numbins = m_fftsize >> 1; //m_fftsize - 2 >> 1;
float * p1= m_fftbuf1; float * p2= m_fftbuf2;
p1[0] *= p2[0]; p1[1] *= p2[1];
//complex multiply for (int i=1; i<numbins; ++i) { float real,imag; int realind,imagind; realind= 2*i; imagind= realind+1; real= p1[realind]*p2[realind]- p1[imagind]*p2[imagind]; imag= p1[realind]*p2[imagind]+ p1[imagind]*p2[realind]; p1[realind] = real; //p2->bin[i]; p1[imagind]= imag; }
//copy second part from before to overlap memcpy(m_overlapbuf, m_outbuf+m_insize, m_insize * sizeof(float));
//inverse fft into outbuf memcpy(m_outbuf, m_fftbuf1, m_fftsize * sizeof(float));
//in place riffts(m_outbuf, log2n, 1, cosTable[log2n]);
DoWindowing(log2n, m_outbuf, m_fftsize); }
//write out samples copied from outbuf, with overlap added in float *output = out[0]; float *nout= m_outbuf+m_pos; float *overlap= m_overlapbuf+m_pos;
for (int i=0; i<numSamples; ++i) { *++output = *++nout + *++overlap; }
}
--- sc*.cpp DELETED ---
--- NEW FILE: fftlib.h --- long FFTInit(long *fftMptr, long fftN, float *Utbl); /* Compute cosine table and check size for complex ffts */ /* INPUTS */ /* fftN = size of fft */ /* OUTPUTS */ /* *fftMptr = log2 of fft size */ /* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ /* RETURNS */ /* 1 if fftN is invalid, 0 otherwise */
long rFFTInit(long *fftMptr, long fftN, float *Utbl); /* Compute cosine table and check size for a real input fft */ /* INPUTS */ /* fftN = size of fft */ /* OUTPUTS */ /* *fftMptr = log2 of fft size */ /* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ /* RETURNS */ /* 1 if fftN is invalid, 0 otherwise */
void ffts(float *ioptr, long M, long Rows, float *Utbl); /* Compute in-place complex fft on the rows of the input array */ /* INPUTS */ /* M = log2 of fft size */ /* *ioptr = input data array */ /* *Utbl = cosine table */ /* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ /* OUTPUTS */ /* *ioptr = output data array */
void iffts(float *ioptr, long M, long Rows, float *Utbl); /* Compute in-place inverse complex fft on the rows of the input array */ /* INPUTS */ /* M = log2 of fft size */ /* *ioptr = input data array */ /* *Utbl = cosine table */ /* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ /* OUTPUTS */ /* *ioptr = output data array */
void rffts(float *ioptr, long M, long Rows, float *Utbl); /* Compute in-place real fft on the rows of the input array */ /* INPUTS */ /* M = log2 of fft size */ /* *ioptr = real input data array */ /* *Utbl = cosine table */ /* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ /* OUTPUTS */ /* *ioptr = output data array in the following order */ /* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */
void riffts(float *ioptr, long M, long Rows, float *Utbl); /* Compute in-place real ifft on the rows of the input array */ /* INPUTS */ /* M = log2 of fft size */ /* *ioptr = input data array in the following order */ /* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ /* *Utbl = cosine table */ /* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ /* OUTPUTS */ /* *ioptr = real output data array */
--- NEW FILE: fftlib.c --- /* FFT library */ /* Library of in-place fast fourier transforms */ /* Forward and inverse complex transforms */ /* and real forward transform */ /* Optimized for RISC processors with many registers */ /* Version 1.1 John Green NUWC New London CT January 96 */ /* Version 1.1 renamed as fftlib from fftbig */ /* Version 1.1 removed (float *)((char *) ptr) optimization */ /* Version 1.0 John Green NUWC New London CT December 95 */ /* (John Green) green_jt@vsdec.nl.nuwc.navy.mil */ /* green_jt@vsdec.nl.nuwc.navy.mil */
#include <math.h> #include "fftlib.h"
#define MAXMROOT 9 /* 2^(MAXMROOT-1) = # of elements in BRcnt */
/* Bit reversed counter */ static const unsigned char BRcnt[256] = { [...3267 lines suppressed...] NsameU4 = -NsameU4;
if(stage&1){ LoopN >>= 3; NsameU1 >>= 3; NsameU2 >>= 3; NsameU4 >>= 3; NdiffU <<= 3; Flyinc = Flyinc << 3; FlyOffsetA <<= 3; FlyOffsetB <<= 3; FlyOffsetAIm = FlyOffsetA + 1; FlyOffsetBIm = FlyOffsetB + 1; } } M=M+1; /* for RIFFT */
ioptr += Ntbl[M]; } }