[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[sc-dev] SF.net SVN: supercollider:[8131] trunk/Source/plugins/Convolution.cpp
Revision: 8131
http://supercollider.svn.sourceforge.net/supercollider/?rev=8131&view=rev
Author: sicklincoln
Date: 2008-12-15 00:25:22 +0000 (Mon, 15 Dec 2008)
Log Message:
-----------
Convolution2 adapted to use sc_fft
Modified Paths:
--------------
trunk/Source/plugins/Convolution.cpp
Modified: trunk/Source/plugins/Convolution.cpp
===================================================================
--- trunk/Source/plugins/Convolution.cpp 2008-12-14 22:57:26 UTC (rev 8130)
+++ trunk/Source/plugins/Convolution.cpp 2008-12-15 00:25:22 UTC (rev 8131)
@@ -18,7 +18,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-//Convolution by sick lincoln for sc3
+//Convolution by nick collins for sc3 (later input from Marije as below, Dan Stowell and Nick worked on sc_fft compatibility late 2008)
//see ch18 http://www.dspguide.com/ch18.htm Steven W Smith
//Convolution2 adapted by marije baalman for triggered kernel swap, with help from alberto de campo
@@ -52,10 +52,12 @@
struct Convolution2 : Unit
{
- int m_pos, m_insize, m_fftsize,m_mask;
- int m_log2n;
+ int m_pos, m_insize, m_fftsize; //,m_mask;
+ //int m_log2n;
float m_prevtrig;
float *m_inbuf1, *m_fftbuf1, *m_fftbuf2, *m_outbuf,*m_overlapbuf;
+ scfft *m_scfft1, *m_scfft2, *m_scfftR;
+ float *m_trbuf;
};
struct Convolution2L : Unit
@@ -267,7 +269,7 @@
{
//require size N+M-1 to be a power of two
- unit->m_insize=(int)ZIN0(3); //could be input parameter
+ unit->m_insize=(int)ZIN0(3); //could be input parameter
// printf( "unit->m_insize %i\n", unit->m_insize );
// printf( "unit->mWorld->mFullRate.mBufLength %i\n", unit->mWorld->mFullRate.mBufLength );
@@ -289,34 +291,62 @@
int insize = unit->m_insize * sizeof(float);
int fftsize = unit->m_fftsize * sizeof(float);
- unit->m_inbuf1 = (float*)RTAlloc(unit->mWorld, insize);
-// unit->m_inbuf2 = (float*)RTAlloc(unit->mWorld, insize);
+//
+// unit->m_inbuf1 = (float*)RTAlloc(unit->mWorld, insize);
+//// unit->m_inbuf2 = (float*)RTAlloc(unit->mWorld, insize);
+//
+// unit->m_fftbuf1 = (float*)RTAlloc(unit->mWorld, fftsize);
+// unit->m_fftbuf2 = (float*)RTAlloc(unit->mWorld, fftsize);
+
+ unit->m_inbuf1 = (float*)RTAlloc(unit->mWorld, insize);
unit->m_fftbuf1 = (float*)RTAlloc(unit->mWorld, fftsize);
unit->m_fftbuf2 = (float*)RTAlloc(unit->mWorld, fftsize);
+
+ unit->m_outbuf = (float*)RTAlloc(unit->mWorld, fftsize);
+ unit->m_overlapbuf = (float*)RTAlloc(unit->mWorld, insize);
+
+ memset(unit->m_outbuf, 0, fftsize);
+ memset(unit->m_overlapbuf, 0, insize);
+
+ //unit->m_log2n = LOG2CEIL(unit->m_fftsize);
+
+ unit->m_pos = 0;
+
+ unit->m_trbuf = (float*)RTAlloc(unit->mWorld, scfft_trbufsize(unit->m_fftsize));
+ unit->m_scfft1 = (scfft*)RTAlloc(unit->mWorld, sizeof(scfft));
+ unit->m_scfft2 = (scfft*)RTAlloc(unit->mWorld, sizeof(scfft));
+ unit->m_scfftR = (scfft*)RTAlloc(unit->mWorld, sizeof(scfft));
+
+ unit->m_outbuf = (float*)RTAlloc(unit->mWorld, fftsize);
+ unit->m_overlapbuf = (float*)RTAlloc(unit->mWorld, insize);
+ memset(unit->m_outbuf, 0, fftsize);
+ memset(unit->m_overlapbuf, 0, insize);
+
+ scfft_create(unit->m_scfft1, unit->m_fftsize, unit->m_fftsize, -1, unit->m_fftbuf1, unit->m_fftbuf1, unit->m_trbuf, true);
+ scfft_create(unit->m_scfft2, unit->m_fftsize, unit->m_fftsize, -1, unit->m_fftbuf2, unit->m_fftbuf2, unit->m_trbuf, true);
+ scfft_create(unit->m_scfftR, unit->m_fftsize, unit->m_fftsize, -1, unit->m_fftbuf1, unit->m_outbuf, unit->m_trbuf, false);
+
//calculate fft for kernel straight away
memcpy(unit->m_fftbuf2, buf->data, insize);
//zero pad second part of buffer to allow for convolution
- memset(unit->m_fftbuf2+unit->m_insize, 0, insize);
+ memset(unit->m_fftbuf2+unit->m_insize, 0, insize);
- unit->m_log2n = LOG2CEIL(unit->m_fftsize);
+ scfft_dofft(unit->m_scfft2);
- int log2n = unit->m_log2n;
-
- //test for full input buffer
- unit->m_mask = unit->m_insize;
unit->m_pos = 0;
- //in place transform for now
- rffts(unit->m_fftbuf2, log2n, 1, cosTable[log2n]);
+// unit->m_log2n = LOG2CEIL(unit->m_fftsize);
+//
+// int log2n = unit->m_log2n;
+//
+// //test for full input buffer
+// //unit->m_mask = unit->m_insize;
+//
+// //in place transform for now
+// rffts(unit->m_fftbuf2, log2n, 1, cosTable[log2n]);
- unit->m_outbuf = (float*)RTAlloc(unit->mWorld, fftsize);
- unit->m_overlapbuf = (float*)RTAlloc(unit->mWorld, insize);
-
- memset(unit->m_outbuf, 0, fftsize);
- memset(unit->m_overlapbuf, 0, insize);
-
unit->m_prevtrig = 0.f;
unit->m_prevtrig = ZIN0(2);
@@ -330,8 +360,10 @@
}
else
{
- printf( "insize smaller than blocksize\n" );
- SETCALC(Convolution2_next2);
+ printf( "Convolution2 framesize smaller than blocksize \n" );
+ SETCALC(*ClearUnitOutputs);
+ unit->mDone = true;
+ //SETCALC(Convolution2_next2);
}
}
@@ -343,6 +375,16 @@
RTFree(unit->mWorld, unit->m_fftbuf2);
RTFree(unit->mWorld, unit->m_outbuf);
RTFree(unit->mWorld, unit->m_overlapbuf);
+
+ RTFree(unit->mWorld, unit->m_trbuf);
+
+ scfft_destroy(unit->m_scfft1);
+ scfft_destroy(unit->m_scfft2);
+ scfft_destroy(unit->m_scfftR);
+ RTFree(unit->mWorld, unit->m_scfft1);
+ RTFree(unit->mWorld, unit->m_scfft2);
+ RTFree(unit->mWorld, unit->m_scfftR);
+
}
@@ -366,7 +408,7 @@
if (unit->m_prevtrig <= 0.f && curtrig > 0.f){
float fbufnum = ZIN0(1);
- int log2n2 = unit->m_log2n;
+ //int log2n2 = unit->m_log2n;
uint32 bufnum = (int)fbufnum;
//printf("bufnum %i \n", bufnum);
World *world = unit->mWorld;
@@ -375,8 +417,9 @@
memcpy(unit->m_fftbuf2, buf->data, insize);
memset(unit->m_fftbuf2+unit->m_insize, 0, insize);
- //DoWindowing(log2n2, unit->m_fftbuf2, unit->m_fftsize);
- rffts(unit->m_fftbuf2, log2n2, 1, cosTable[log2n2]);
+ //rffts(unit->m_fftbuf2, log2n2, 1, cosTable[log2n2]);
+
+ scfft_dofft(unit->m_scfft2);
}
if (unit->m_pos & unit->m_insize) {
@@ -385,7 +428,7 @@
unit->m_pos = 0; //reset collection counter
// copy to fftbuf
- int log2n = unit->m_log2n;
+ //int log2n = unit->m_log2n;
memcpy(unit->m_fftbuf1, unit->m_inbuf1, insize);
@@ -393,9 +436,10 @@
memset(unit->m_fftbuf1+unit->m_insize, 0, insize);
//if (unit->m_prevtrig <= 0.f && curtrig > 0.f)
+ scfft_dofft(unit->m_scfft1);
+
//in place transform for now
- rffts(unit->m_fftbuf1, log2n, 1, cosTable[log2n]);
- //#endif
+// rffts(unit->m_fftbuf1, log2n, 1, cosTable[log2n]);
//complex multiply time
int numbins = unit->m_fftsize >> 1; //unit->m_fftsize - 2 >> 1;
@@ -418,14 +462,16 @@
}
//copy second part from before to overlap
- memcpy(unit->m_overlapbuf, unit->m_outbuf+unit->m_insize, unit->m_insize * sizeof(float));
+ memcpy(unit->m_overlapbuf, unit->m_outbuf+unit->m_insize, insize);
//inverse fft into outbuf
memcpy(unit->m_outbuf, unit->m_fftbuf1, unit->m_fftsize * sizeof(float));
//in place
- riffts(unit->m_outbuf, log2n, 1, cosTable[log2n]);
+ //riffts(unit->m_outbuf, log2n, 1, cosTable[log2n]);
+ scfft_doifft(unit->m_scfftR);
+
// DoWindowing(log2n, unit->m_outbuf, unit->m_fftsize);
}
@@ -442,98 +488,101 @@
}
-// if kernel size is smaller than server block size (note: this is not working yet...)
-void Convolution2_next2(Convolution2 *unit, int wrongNumSamples)
-{
-
- float *in1 = IN(0);
- //float *in2 = IN(1);
- float curtrig = ZIN0(2);
-
- float *out1 = unit->m_inbuf1; // unit->m_pos is now a pointer into the *in1 buffer
-// float *out2 = unit->m_inbuf2 + unit->m_pos;
- unit->m_pos = 0;
- int numSamples = unit->mWorld->mFullRate.mBufLength;
- uint32 insize=unit->m_insize * sizeof(float);
+// flawed since assumes framesize at least divides blocksize. framesize has to be power of two anyway: commenting out pending deletion
+//// if kernel size is smaller than server block size (note: this is not working yet...
+//void Convolution2_next2(Convolution2 *unit, int wrongNumSamples)
+//{
+//
+// float *in1 = IN(0);
+// //float *in2 = IN(1);
+// float curtrig = ZIN0(2);
+//
+// float *out1 = unit->m_inbuf1; // unit->m_pos is now a pointer into the *in1 buffer
+//// float *out2 = unit->m_inbuf2 + unit->m_pos;
+//
+// unit->m_pos = 0;
+//
+// int numSamples = unit->mWorld->mFullRate.mBufLength;
+// uint32 insize=unit->m_insize * sizeof(float);
+//
+// int numTimes = numSamples / unit->m_insize;
+//
+//// replace buffer if there was a trigger
+// if (unit->m_prevtrig <= 0.f && curtrig > 0.f){
+// float fbufnum = ZIN0(1);
+// int log2n2 = unit->m_log2n;
+// uint32 bufnum = (int)fbufnum;
+// //printf("bufnum %i \n", bufnum);
+// World *world = unit->mWorld;
+// if (bufnum >= world->mNumSndBufs) bufnum = 0;
+// SndBuf *buf = world->mSndBufs + bufnum;
+//
+// memcpy(unit->m_fftbuf2, buf->data, insize);
+// memset(unit->m_fftbuf2+unit->m_insize, 0, insize);
+// //DoWindowing(log2n2, unit->m_fftbuf2, unit->m_fftsize);
+// rffts(unit->m_fftbuf2, log2n2, 1, cosTable[log2n2]);
+// }
+//
+// for ( int i=0; i < numTimes; i++ )
+// {
+// // copy input
+// Copy(unit->m_insize, out1, in1 + unit->m_pos);
+// unit->m_pos += unit->m_insize;
+//
+// //have collected enough samples to transform next frame
+// // copy to fftbuf
+// int log2n = unit->m_log2n;
+//
+// memcpy(unit->m_fftbuf1, unit->m_inbuf1, insize);
+// //zero pad second part of buffer to allow for convolution
+// memset(unit->m_fftbuf1+unit->m_insize, 0, insize);
+//
+// //in place transform for now
+// rffts(unit->m_fftbuf1, log2n, 1, cosTable[log2n]);
+//
+// //complex multiply time
+// int numbins = unit->m_fftsize >> 1; //unit->m_fftsize - 2 >> 1;
+//
+// float * p1= unit->m_fftbuf1;
+// float * p2= unit->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(unit->m_overlapbuf, unit->m_outbuf+unit->m_insize, unit->m_insize * sizeof(float));
+//
+// //inverse fft into outbuf
+// memcpy(unit->m_outbuf, unit->m_fftbuf1, unit->m_fftsize * sizeof(float));
+//
+// //in place
+// riffts(unit->m_outbuf, log2n, 1, cosTable[log2n]);
+//
+// //write out samples copied from outbuf, with overlap added in
+// float *output = ZOUT(0);
+// float *out= unit->m_outbuf;
+// float *overlap= unit->m_overlapbuf;
+//
+// for (int i=0; i<unit->m_insize; ++i) {
+// *++output = *++out + *++overlap;
+// }
+// }
+// unit->m_prevtrig = curtrig;
+//}
- int numTimes = numSamples / unit->m_insize;
-
-// replace buffer if there was a trigger
- if (unit->m_prevtrig <= 0.f && curtrig > 0.f){
- float fbufnum = ZIN0(1);
- int log2n2 = unit->m_log2n;
- uint32 bufnum = (int)fbufnum;
- //printf("bufnum %i \n", bufnum);
- World *world = unit->mWorld;
- if (bufnum >= world->mNumSndBufs) bufnum = 0;
- SndBuf *buf = world->mSndBufs + bufnum;
-
- memcpy(unit->m_fftbuf2, buf->data, insize);
- memset(unit->m_fftbuf2+unit->m_insize, 0, insize);
- //DoWindowing(log2n2, unit->m_fftbuf2, unit->m_fftsize);
- rffts(unit->m_fftbuf2, log2n2, 1, cosTable[log2n2]);
- }
-
- for ( int i=0; i < numTimes; i++ )
- {
- // copy input
- Copy(unit->m_insize, out1, in1 + unit->m_pos);
- unit->m_pos += unit->m_insize;
-
- //have collected enough samples to transform next frame
- // copy to fftbuf
- int log2n = unit->m_log2n;
-
- memcpy(unit->m_fftbuf1, unit->m_inbuf1, insize);
- //zero pad second part of buffer to allow for convolution
- memset(unit->m_fftbuf1+unit->m_insize, 0, insize);
-
- //in place transform for now
- rffts(unit->m_fftbuf1, log2n, 1, cosTable[log2n]);
-
- //complex multiply time
- int numbins = unit->m_fftsize >> 1; //unit->m_fftsize - 2 >> 1;
-
- float * p1= unit->m_fftbuf1;
- float * p2= unit->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(unit->m_overlapbuf, unit->m_outbuf+unit->m_insize, unit->m_insize * sizeof(float));
-
- //inverse fft into outbuf
- memcpy(unit->m_outbuf, unit->m_fftbuf1, unit->m_fftsize * sizeof(float));
-
- //in place
- riffts(unit->m_outbuf, log2n, 1, cosTable[log2n]);
-
- //write out samples copied from outbuf, with overlap added in
- float *output = ZOUT(0);
- float *out= unit->m_outbuf;
- float *overlap= unit->m_overlapbuf;
-
- for (int i=0; i<unit->m_insize; ++i) {
- *++output = *++out + *++overlap;
- }
- }
- unit->m_prevtrig = curtrig;
-}
-
void Convolution2L_Ctor(Convolution2L *unit)
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
_______________________________________________
sc-dev mailing list
info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: https://listarc.bham.ac.uk/marchives/sc-dev/
search: https://listarc.bham.ac.uk/lists/sc-dev/search/