[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/