void Convolution_Ctor(Convolution *unit)
{
	//require size N+M-1 to be a power of two
	unit->m_insize=(int)ZIN0(2);

	//         printf("hello %i /n", unit->m_insize);
	unit->m_fftsize=2*(unit->m_insize);
	//just use memory for the input buffers and fft buffers
	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_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;

	SCWorld_Allocator alloc(ft, unit->mWorld);
	unit->m_scfft1 = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_fftbuf1, unit->m_fftbuf1, kForward, alloc);
	unit->m_scfft2 = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_fftbuf2, unit->m_fftbuf2, kForward, alloc);
	unit->m_scfftR = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_fftbuf1, unit->m_outbuf, kBackward, alloc);

	SETCALC(Convolution_next);
}
Exemple #2
0
void IFFT_Ctor(IFFT* unit){
	unit->m_wintype = (int)ZIN0(1); // wintype may be used by the base ctor
	if(!FFTBase_Ctor(unit, 2)){
		SETCALC(*ClearUnitOutputs);
		// These zeroes are to prevent the dtor freeing things that don't exist:
		unit->m_olabuf = 0;
		return;
	}

	// This will hold the transformed and progressively overlap-added data ready for outputting.
	unit->m_olabuf = (float*)RTAlloc(unit->mWorld, unit->m_audiosize * sizeof(float));
	memset(unit->m_olabuf, 0, unit->m_audiosize * sizeof(float));

	SCWorld_Allocator alloc(ft, unit->mWorld);
	unit->m_scfft = scfft_create(unit->m_fullbufsize, unit->m_audiosize, (SCFFT_WindowFunction)unit->m_wintype, unit->m_fftsndbuf->data,
								 unit->m_fftsndbuf->data, kBackward, alloc);

	// "pos" will be reset to zero when each frame comes in. Until then, the following ensures silent output at first:
	unit->m_pos = 0; //unit->m_audiosize;

	if (unit->mCalcRate == calc_FullRate) {
		unit->m_numSamples = unit->mWorld->mFullRate.mBufLength;
	} else {
		unit->m_numSamples = 1;
	}

	SETCALC(IFFT_next);
}
//buffer preparation
void PreparePartConv(World *world, struct SndBuf *buf, struct sc_msg_iter *msg)
{
	// 'channels' not used- should just be mono, num frames= num samples
	float *data1 = buf->data;
	uint32 frombufnum = msg->geti();
	int fftsize = msg->geti();

	//output size must be frombuf->frames*2
	if (frombufnum >= world->mNumSndBufs) frombufnum = 0;
	SndBuf* frombuf = world->mSndBufs + frombufnum;
	int frames2 = frombuf->frames;
	float *data2 = frombuf->data;

	//scfft
	int nover2= fftsize>>1;

	int numpartitions;
	if(frames2 % nover2 == 0){
		numpartitions= frames2/nover2;
	}else{
		numpartitions= (frames2/nover2)+1;
	}

	//printf("reality check numpartitions %d fftsize %d product %d numinputframes %d \n", numpartitions, fftsize, numpartitions*fftsize, frames2);

	float * inputbuf= (float*)RTAlloc(world, fftsize * sizeof(float));
	float * spectrum= (float*)RTAlloc(world, fftsize * sizeof(float));

	SCWorld_Allocator alloc(ft, world);
	scfft* m_scfft = scfft_create(fftsize, fftsize, kRectWindow, inputbuf, spectrum, kForward, alloc);

	memset(inputbuf, 0, sizeof(float)*fftsize); // for zero padding

	//run through input data buffer, taking nover2 chunks, zero padding each
	for (int i=0; i<numpartitions; ++i) {
		int indexnow= nover2*i;
		int indexout= fftsize*i;

		if(i<(numpartitions-1)){
			memcpy(inputbuf, data2+indexnow, nover2 * sizeof(float));
		}else{
			int takenow = frames2 % nover2;
			if(takenow == 0){
				takenow = nover2;
			}

			memcpy(inputbuf, data2+indexnow, takenow * sizeof(float));
			if(takenow<nover2){
				memset(inputbuf+takenow, 0, (nover2-takenow)*sizeof(float));
			}
		}
		scfft_dofft(m_scfft);
		memcpy(data1+indexout, spectrum, fftsize * sizeof(float));
	}
	//clean up
	RTFree(world, inputbuf);
	RTFree(world, spectrum);

	if(m_scfft) scfft_destroy(m_scfft, alloc);
}
Exemple #4
0
void FFT_Ctor(FFT *unit)
{
	int winType = sc_clip((int)ZIN0(3), -1, 1); // wintype may be used by the base ctor
	unit->m_wintype = winType;
	if(!FFTBase_Ctor(unit, 5)){
		SETCALC(FFT_ClearUnitOutputs);
		// These zeroes are to prevent the dtor freeing things that don't exist:
		unit->m_inbuf = 0;
		unit->m_scfft = 0;
		return;
	}
	int audiosize = unit->m_audiosize * sizeof(float);

	int hopsize = (int)(sc_max(sc_min(ZIN0(2), 1.f), 0.f) * unit->m_audiosize);
	if (hopsize < unit->mWorld->mFullRate.mBufLength) {
		Print("FFT_Ctor: hopsize smaller than SC's block size (%i) - automatically corrected.\n", hopsize, unit->mWorld->mFullRate.mBufLength);
		hopsize = unit->mWorld->mFullRate.mBufLength;
	} else if (((int)(hopsize / unit->mWorld->mFullRate.mBufLength)) * unit->mWorld->mFullRate.mBufLength
				!= hopsize) {
		Print("FFT_Ctor: hopsize (%i) not an exact multiple of SC's block size (%i) - automatically corrected.\n", hopsize, unit->mWorld->mFullRate.mBufLength);
		hopsize = ((int)(hopsize / unit->mWorld->mFullRate.mBufLength)) * unit->mWorld->mFullRate.mBufLength;
	}
	unit->m_hopsize = hopsize;
	unit->m_shuntsize = unit->m_audiosize - hopsize;

	unit->m_inbuf = (float*)RTAlloc(unit->mWorld, audiosize);

	SCWorld_Allocator alloc(ft, unit->mWorld);
	unit->m_scfft = scfft_create(unit->m_fullbufsize, unit->m_audiosize, (SCFFT_WindowFunction)unit->m_wintype, unit->m_inbuf,
								 unit->m_fftsndbuf->data, kForward, alloc);

	if (!unit->m_scfft) {
		SETCALC(*ClearUnitOutputs);
		return;
	}

	memset(unit->m_inbuf, 0, audiosize);

	//Print("FFT_Ctor: hopsize %i, shuntsize %i, bufsize %i, wintype %i, \n",
	//	unit->m_hopsize, unit->m_shuntsize, unit->m_bufsize, unit->m_wintype);

	if (INRATE(1) == calc_FullRate) {
		unit->m_numSamples = unit->mWorld->mFullRate.mBufLength;
	} else {
		unit->m_numSamples = 1;
	}

	SETCALC(FFT_next);
}
Exemple #5
0
void FFT_Ctor(FFT *unit)
{
	unit->m_wintype = (int)ZIN0(3); // wintype may be used by the base ctor
	if(!FFTBase_Ctor(unit, 5)){
		SETCALC(FFT_ClearUnitOutputs);
		// These zeroes are to prevent the dtor freeing things that don't exist:
		unit->m_inbuf = 0;
		unit->m_transformbuf = 0;
		unit->m_scfft = 0;
		return;
	}
	int fullbufsize = unit->m_fullbufsize * sizeof(float);
	int audiosize = unit->m_audiosize * sizeof(float);

	int hopsize = (int)(sc_max(sc_min(ZIN0(2), 1.f), 0.f) * unit->m_audiosize);
	if (((int)(hopsize / unit->mWorld->mFullRate.mBufLength)) * unit->mWorld->mFullRate.mBufLength
				!= hopsize) {
		Print("FFT_Ctor: hopsize (%i) not an exact multiple of SC's block size (%i) - automatically corrected.\n", hopsize, unit->mWorld->mFullRate.mBufLength);
		hopsize = ((int)(hopsize / unit->mWorld->mFullRate.mBufLength)) * unit->mWorld->mFullRate.mBufLength;
	}
	unit->m_hopsize = hopsize;
	unit->m_shuntsize = unit->m_audiosize - hopsize;

	unit->m_inbuf = (float*)RTAlloc(unit->mWorld, audiosize);

	unit->m_transformbuf = (float*)RTAlloc(unit->mWorld, scfft_trbufsize(unit->m_fullbufsize));
	unit->m_scfft        = (scfft*)RTAlloc(unit->mWorld, sizeof(scfft));
	scfft_create(unit->m_scfft, unit->m_fullbufsize, unit->m_audiosize, unit->m_wintype, unit->m_inbuf, unit->m_fftsndbuf->data, unit->m_transformbuf, true);

	memset(unit->m_inbuf, 0, audiosize);

	//Print("FFT_Ctor: hopsize %i, shuntsize %i, bufsize %i, wintype %i, \n",
	//	unit->m_hopsize, unit->m_shuntsize, unit->m_bufsize, unit->m_wintype);

	if (INRATE(1) == calc_FullRate) {
		unit->m_numSamples = unit->mWorld->mFullRate.mBufLength;
	} else {
		unit->m_numSamples = 1;
	}

	SETCALC(FFT_next);
}
void Convolution2_Ctor(Convolution2 *unit)
{
	//require size N+M-1 to be a power of two

	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 );

	//float fbufnum  = ZIN0(1);
	uint32 bufnum = (int)ZIN0(1); //fbufnum;
	World *world = unit->mWorld;

	//before added check for LocalBuf
	//if (bufnum >= world->mNumSndBufs) bufnum = 0;
	//	SndBuf *buf = world->mSndBufs + bufnum;

	SndBuf *buf = ConvGetBuffer(unit, bufnum, "Convolution2", 1);

	if(buf) {
		if ( unit->m_insize <= 0 ) // if smaller than zero, equal to size of buffer
			unit->m_insize=buf->frames;	//could be input parameter

		unit->m_fftsize=2*(unit->m_insize);
		//printf("hello %i, %i\n", unit->m_insize, unit->m_fftsize);
		//just use memory for the input buffers and fft buffers
		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_fftbuf1 = (float*)RTAlloc(unit->mWorld, fftsize);
		//        unit->m_fftbuf2 = (float*)RTAlloc(unit->mWorld, fftsize);


		unit->m_inbuf1 = (float*)RTAlloc(world, insize);
		unit->m_fftbuf1 = (float*)RTAlloc(world, fftsize);
		unit->m_fftbuf2 = (float*)RTAlloc(world, fftsize);

		unit->m_outbuf = (float*)RTAlloc(world, fftsize);
		unit->m_overlapbuf = (float*)RTAlloc(world, insize);

		memset(unit->m_outbuf, 0, fftsize);
		memset(unit->m_overlapbuf, 0, insize);

		//unit->m_log2n = LOG2CEIL(unit->m_fftsize);

		unit->m_pos = 0;
		memset(unit->m_outbuf, 0, fftsize);
		memset(unit->m_overlapbuf, 0, insize);

		SCWorld_Allocator alloc(ft, unit->mWorld);
		unit->m_scfft1 = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_fftbuf1, unit->m_fftbuf1, kForward, alloc);
		unit->m_scfft2 = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_fftbuf2, unit->m_fftbuf2, kForward, alloc);
		unit->m_scfftR = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_fftbuf1, unit->m_outbuf, kBackward, alloc);

		//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);

		scfft_dofft(unit->m_scfft2);

		unit->m_pos = 0;

		//	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_prevtrig = 0.f;
		unit->m_prevtrig = ZIN0(2);

		// 	printf( "unit->m_insize %i\n", unit->m_insize );
		// 	printf( "world->mFullRate.mBufLength %i\n", world->mFullRate.mBufLength );

		if ( unit->m_insize >= world->mFullRate.mBufLength )
		{
			// 		printf( "insize bigger than blocksize\n" );
			SETCALC(Convolution2_next);
		}
		else
		{
			printf( "Convolution2 framesize smaller than blocksize \n" );
			SETCALC(*ClearUnitOutputs);
			unit->mDone = true;
			//SETCALC(Convolution2_next2);
		}
	} else {
		unit->m_scfft2 = unit->m_scfft1 = unit->m_scfftR = NULL;
	}
}
void PartConv_Ctor( PartConv* unit )
{
	unit->m_fftsize= (int) ZIN0(1);
	unit->m_nover2= unit->m_fftsize>>1;

	unit->m_inputbuf= (float*)RTAlloc(unit->mWorld, unit->m_fftsize * sizeof(float));
	unit->m_spectrum= (float*)RTAlloc(unit->mWorld, unit->m_fftsize * sizeof(float));

	SCWorld_Allocator alloc(ft, unit->mWorld);
	unit->m_scfft = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_inputbuf, unit->m_spectrum, kForward, alloc);

	//inverse
	unit->m_inputbuf2= (float*)RTAlloc(unit->mWorld, unit->m_fftsize * sizeof(float));
	unit->m_spectrum2= (float*)RTAlloc(unit->mWorld, unit->m_fftsize * sizeof(float));
	//in place this time
	unit->m_scifft = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_inputbuf2, unit->m_spectrum2, kBackward, alloc);

	//debug test: changing scale factors in case amplitude summation is a problem
	//unit->m_scfft->scalefac=1.0/45.254833995939;
	//unit->m_scifft->scalefac=1.0/45.254833995939;

	unit->m_output= (float*)RTAlloc(unit->mWorld, unit->m_fftsize * sizeof(float));
	unit->m_outputpos=0;

	memset(unit->m_output, 0, unit->m_fftsize * sizeof(float));
	memset(unit->m_inputbuf, 0, unit->m_fftsize * sizeof(float));
	unit->m_pos=0;

	//get passed in buffer
	unit->m_fd_accumulate=NULL;

	uint32 bufnum = (uint32)ZIN0(2);
	SndBuf *buf;

	if (bufnum >= unit->mWorld->mNumSndBufs) {
		int localBufNum = bufnum - unit->mWorld->mNumSndBufs;
		Graph *parent = unit->mParent;
		if(localBufNum <= parent->localMaxBufNum) {
			buf = parent->mLocalSndBufs + localBufNum;
		} else {
			printf("PartConv Error: Invalid Spectral data bufnum %d \n", bufnum);
			SETCALC(*ClearUnitOutputs);
			unit->mDone = true;
			return;
		}
	}

	buf = unit->mWorld->mSndBufs + bufnum;

	unit->m_specbufnumcheck = bufnum;

	if (!buf->data) {
		//unit->mDone = true;
		printf("PartConv Error: Spectral data buffer not allocated \n");
		SETCALC(*ClearUnitOutputs);
		unit->mDone = true;
		return;
	}

	unit->m_irspectra = buf->data;
	unit->m_fullsize = buf->samples;
	unit->m_partitions=buf->samples/(unit->m_fftsize); //should be exact
	//printf("another check partitions %d irspecsize %d fftsize %d \n", unit->m_partitions,unit->m_fullsize, unit->m_fftsize);

	if((buf->samples % unit->m_fftsize !=0) || (buf->samples==0)) {
		printf("PartConv Error: fftsize doesn't divide spectral data buffer size or spectral data buffer size is zero\n");
		SETCALC(*ClearUnitOutputs);
		unit->mDone = true;
		return;
	}

	//CHECK SAMPLING RATE AND BUFFER SIZE
	unit->m_blocksize = unit->mWorld->mFullRate.mBufLength;
	//if(unit->m_blocksize!=64) printf("TPV complains: block size not 64, you have %d\n", unit->m_blocksize);
	unit->m_sr = unit->mWorld->mSampleRate;
	//if(unit->m_sr!=44100) printf("TPV complains: sample rate not 44100, you have %d\n", unit->m_sr);

	if(unit->m_nover2 % unit->m_blocksize !=0) {
		printf("PartConv Error: block size doesn't divide partition size\n");
		SETCALC(*ClearUnitOutputs);
		unit->mDone = true;
		return;
	} else {

		//must be exact divisor
		int blocksperpartition = unit->m_nover2/unit->m_blocksize;

		unit->m_spareblocks = blocksperpartition-1;

		if(unit->m_spareblocks<1) {
			printf("PartConv Error: no spareblocks, amortisation not possible! \n");
			SETCALC(*ClearUnitOutputs);
			unit->mDone = true;
			return;
		}

		//won't be exact
		unit->m_numamort = (unit->m_partitions-1)/unit->m_spareblocks; //will relate number of partitions to number of spare blocks
		unit->m_lastamort= (unit->m_partitions-1)- ((unit->m_spareblocks-1)*(unit->m_numamort)); //allow for error on last one
		unit->m_amortcount= -1; //starts as flag to avoid any amortisation before have first fft done
		unit->m_partitionsdone=1;

		//printf("Amortisation stats partitions %d nover2 %d blocksize %d spareblocks %d numamort %d lastamort %d \n", unit->m_partitions,unit->m_nover2, unit->m_blocksize, unit->m_spareblocks, unit->m_numamort, unit->m_lastamort);

		unit->m_fd_accumulate= (float*)RTAlloc(unit->mWorld, unit->m_fullsize * sizeof(float));
		memset(unit->m_fd_accumulate, 0, unit->m_fullsize * sizeof(float));
		unit->m_fd_accum_pos=0;

		SETCALC(PartConv_next);
	}
}
void Convolution2_Ctor(Convolution2 *unit)
{
	//require size N+M-1 to be a power of two
	unit->m_framesize=(int)ZIN0(3);
	uint32 kernelbufnum = (int)ZIN0(1);
	World *world = unit->mWorld;

	SndBuf *kernelbuf = ConvGetBuffer(unit, kernelbufnum, "Convolution2", 1);

	if(kernelbuf) {
		if ( unit->m_framesize <= 0 ){ // if smaller than zero, we use the size of the buffer
			unit->m_framesize=kernelbuf->frames;
		}

		unit->m_fftsize=2*(unit->m_framesize);

		if(unit->m_fftsize > SC_FFT_ABSOLUTE_MAXSIZE){
			printf( "Convolution2: FFT size is larger than SC_FFT_ABSOLUTE_MAXSIZE, cannot run. We suggest PartConv instead.\n" );
			SETCALC(*ClearUnitOutputs);
		}

		// allocate memory internally for the input buffers and fft buffers
		int framesize_f = unit->m_framesize * sizeof(float);
		int fftsize_f = unit->m_fftsize * sizeof(float);
		unit->m_inbuf1 = (float*)RTAlloc(world, framesize_f);
		unit->m_fftbuf1 = (float*)RTAlloc(world, fftsize_f);
		unit->m_fftbuf2 = (float*)RTAlloc(world, fftsize_f);

		unit->m_outbuf = (float*)RTAlloc(world, fftsize_f);
		memset(unit->m_outbuf, 0, fftsize_f);
		unit->m_overlapbuf = (float*)RTAlloc(world, framesize_f);
		memset(unit->m_overlapbuf, 0, framesize_f);

		unit->m_pos = 0;

		SCWorld_Allocator alloc(ft, unit->mWorld);
		unit->m_scfft1 = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_fftbuf1, unit->m_fftbuf1, kForward, alloc);
		unit->m_scfft2 = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_fftbuf2, unit->m_fftbuf2, kForward, alloc);
		unit->m_scfftR = scfft_create(unit->m_fftsize, unit->m_fftsize, kRectWindow, unit->m_fftbuf1, unit->m_outbuf, kBackward, alloc);
		if(!unit->m_scfft1 || !unit->m_scfft2 || !unit->m_scfftR){
			printf( "Could not create scfft.\n" );
			SETCALC(*ClearUnitOutputs);
			unit->mDone = true;
			return;
		}
		//calculate fft for kernel straight away
		// we cannot use a kernel larger than the fft size, so truncate if needed. the kernel may be smaller though.
		uint32 framesize = unit->m_framesize;
		size_t kernelcopysize = sc_min(kernelbuf->frames, framesize);
		memcpy(unit->m_fftbuf2, kernelbuf->data, kernelcopysize * sizeof(float));
		//zero pad second part of buffer to allow for convolution
		memset(unit->m_fftbuf2 + kernelcopysize, 0, (2 * framesize - kernelcopysize) * sizeof(float));

		scfft_dofft(unit->m_scfft2);

		unit->m_pos = 0;

		unit->m_prevtrig = 0.f;
		unit->m_prevtrig = ZIN0(2);

		if ( unit->m_framesize >= world->mFullRate.mBufLength ) {
			SETCALC(Convolution2_next);
		} else {
			printf( "Convolution2 framesize smaller than blocksize \n" );
			SETCALC(*ClearUnitOutputs);
			unit->mDone = true;
		}
	} else {
		unit->m_scfft2 = unit->m_scfft1 = unit->m_scfftR = NULL;
		printf("Convolution2_Ctor: can't get kernel buffer, giving up.\n");
		SETCALC(*ClearUnitOutputs);
	}

}