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